# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# target_branch: http://bzr.savannah.gnu.org/r/pdf/libgnupdf/branches\
# /trunk/
# testament_sha1: 824f2d06074bd562233b2f7a99b1d928ca250201
# timestamp: 2008-12-25 16:51:26 +0100
# base_revision_id: address@hidden
#
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog 2008-12-10 20:45:27 +0000
+++ ChangeLog 2008-12-25 15:49:31 +0000
@@ -1,3 +1,72 @@
+2008-12-25 David Vazquez
+
+ * doc/gnupdf.texi (Stream Types): Crypt filters added.
+
+ * src/base/pdf-stm-f-aesv2.c: Adjust to use new crypt module functions.
+
+ * src/base/pdf-stm-f-md5.c: Same.
+
+2008-12-23 David Vazquez
+
+ * doc/gnupdf-tsd.texi: Updated.
+
+ * torture/unit/base/crypt/pdf-crypt-cipher-setkey.c (test_pdf_crypt_cipher_setkey): New tests.
+
+ * torture/unit/base/crypt/pdf-crypt-cipher-decrypt.c: New tests.
+
+ * torture/unit/base/crypt/pdf-crypt-md-write.c (test_pdf_crypt_md_write): New tests.
+
+ * doc/gnupdf.texi (Encryption): Updated.
+
+ * src/base/pdf-crypt-c-aesv2.c: Incremental encryption support added.
+
+ * src/base/pdf-crypt-c-v2.c: Same.
+
+ * src/base/pdf-crypt.h: Same.
+
+2008-12-20 David Vazquez
+
+ * src/base/pdf-crypt.h (pdf_crypt_md_hash): Minor bug fixed.
+
+ * src/base/pdf-stm-buffer.c (pdf_stm_buffer_resize): New function.
+
+2008-12-15 David Vazquez
+
+ * doc/gnupdf-tsd.texi (pdf_crypt_md_hash)
+ (Message digest functions): Updated.
+
+ * torture/unit/base/crypt/pdf-crypt-md-hash.c: New tests.
+
+ * src/base/pdf-crypt.h (pdf_crypt_md_new): The *MD argument should
+ is the last argument.
+
+2008-12-14 David Vazquez
+
+ * src/base/MANIFEST.wiki: Updated.
+
+ * src/base/pdf-stm-f-aesv2.c: New file
+
+ * src/base/pdf-stm-f-v2.c: New file
+
+ * src/base/pdf-stm-f-md5.c: New file
+
+ * src/base/pdf-crypt-c-aesv2.c (pdf_crypt_cipher_aesv2_decrypt):
+ Check padding size is lesser than AESV2_BLKSIZE.
+
+ * torture/unit/base/crypt/pdf-crypt-cipher-decrypt.c: New test.
+
+2008-12-11 David Vazquez
+
+ * torture/unit/base/stm/pdf-stm-read.c: New test.
+
+ * doc/gnupdf-tsd.texi (pdf_crypt_cipher_encrypt): New test documentation.
+ (pdf_stm_write): New tests documentation.
+
+ * torture/unit/base/crypt/pdf-crypt-cipher-encrypt.c: New test
+
+ * torture/unit/base/crypt/pdf-crypt-cipher-decrypt.c: Change
+ `pdf_crypt_cipher_decrypt_001' ciphered buffer and key.
+
2008-12-10 Jose E. Marchesi
* torture/unit/runtests.c (main): Dont set the CK_FORK variable,
=== modified file 'doc/gnupdf-tsd.texi'
--- doc/gnupdf-tsd.texi 2008-12-02 23:18:59 +0000
+++ doc/gnupdf-tsd.texi 2008-12-25 15:49:31 +0000
@@ -920,6 +920,16 @@
@end table
@end deffn
address@hidden Test pdf_stm_read_011
+Create a memory-based reading stream and attach a cipher filter
+decoder to it.
address@hidden @strong
address@hidden Success condition
+The decoded data should be correct.
address@hidden table
address@hidden deffn
+
+
@node pdf_stm_read_char
@subsubsection pdf_stm_read_char
@@ -1058,6 +1068,49 @@
@end deffn
address@hidden Test pdf_stm_write_008
+Create a memory-based writing stream and attach an V2 filter without parameters.
address@hidden @strong
address@hidden Success condition
+The installation of the filter should fail.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_stm_write_009
+Create a memory-based writing stream and attach a V2 cipher filter to
+encode it.
address@hidden @strong
address@hidden Success condition
+The encoded data should be correct.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_stm_write_010
+Create a memory-based writing stream and attach an AESV2 cipher filter to
+encode it.
address@hidden @strong
address@hidden Success condition
+The encoded data should be correct.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_stm_write_011
+Create a memory-based writing stream and attach an MD5 filter to
+encode it.
address@hidden @strong
address@hidden Success condition
+The encoded data should be correct.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_stm_write_012
+Create a memory-based writing stream and attach an AESv2 cipher filter to
+encode it.
address@hidden @strong
address@hidden Success condition
+The encoded data should be correct.
address@hidden table
address@hidden deffn
@node Text Module
@@ -6063,12 +6116,11 @@
* pdf_crypt_cipher_new::
* pdf_crypt_cipher_destroy::
* pdf_crypt_cipher_setkey::
-* pdf_crypt_cipher_encrypt_size::
-* pdf_crypt_cipher_decrypt_size::
* pdf_crypt_cipher_encrypt::
* pdf_crypt_cipher_decrypt::
* pdf_crypt_md_new::
-* pdf_crypt_md_hash::
+* pdf_crypt_md_write::
+* pdf_crypt_md_read::
* pdf_crypt_md_destroy::
@end menu
@@ -6116,83 +6168,9 @@
@end deffn
address@hidden pdf_crypt_cipher_encrypt_size
address@hidden pdf_crypt_cipher_encrypt_size
-
address@hidden Test pdf_crypt_cipher_encrypt_size_001
-Get the ciphered buffer size for an empty input buffer (AESV2).
address@hidden @strong
address@hidden Success condition
-Returns 32
address@hidden table
address@hidden deffn
-
address@hidden Test pdf_crypt_cipher_encrypt_size_002
-Get the ciphered buffer size for a 15 bytes buffer (AESV2).
address@hidden @strong
address@hidden Success condition
-Returns 32
address@hidden table
address@hidden deffn
-
address@hidden Test pdf_crypt_cipher_encrypt_size_003
-Get the ciphered buffer size for an empty buffer (V2).
address@hidden @strong
address@hidden Success condition
-Returns 0
address@hidden table
address@hidden deffn
-
address@hidden Test pdf_crypt_cipher_encrypt_size_004
-Get the ciphered buffer size for a 15 bytes buffer in a (V2).
address@hidden @strong
address@hidden Success condition
-Returns 15
address@hidden table
address@hidden deffn
-
-
@node pdf_crypt_cipher_setkey
@subsubsection pdf_crypt_cipher_setkey
address@hidden Test pdf_crypt_cipher_setkey_001
-Try set a empty key for a cipher (AESV2).
address@hidden @strong
address@hidden Success condition
-Returns PDF_EBADDATA
address@hidden table
address@hidden deffn
-
-
address@hidden Test pdf_crypt_cipher_setkey_001
-Set a key for a cipher (AESV2).
address@hidden @strong
address@hidden Success condition
-Returns PDF_OK
address@hidden table
address@hidden deffn
-
-
-
-
address@hidden pdf_crypt_cipher_decrypt_size
address@hidden pdf_crypt_cipher_decrypt_size
-
address@hidden Test pdf_crypt_cipher_decrypt_size_001
address@hidden @strong
-Get the plain buffer size for a 32 bytes ciphered buffer (AESV2).
address@hidden Success condition
-Returns 0
address@hidden table
address@hidden deffn
-
address@hidden Test pdf_crypt_cipher_decrypt_size_002
address@hidden @strong
-Get the plain buffer size for a 15 bytes ciphered buffer (V2).
address@hidden Success condition
-Returns 15
address@hidden table
address@hidden deffn
@node pdf_crypt_cipher_encrypt
@@ -6208,9 +6186,17 @@
@deffn Test pdf_crypt_cipher_encrypt_002
@table @strong
-Encrypt an empty buffer (V2).
address@hidden Success condition
-Returns PDF_OK
+Encrypt an ciphered buffer (AESV2).
address@hidden Success condition
+The output data should be correct.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_crypt_cipher_encrypt_003
address@hidden @strong
+Encrypt an ciphered buffer incrementally (AESV2).
address@hidden Success condition
+The output data should be correct.
@end table
@end deffn
@@ -6220,9 +6206,9 @@
@deffn Test pdf_crypt_cipher_decrypt_001
@table @strong
-Decrypt an ciphered empty buffer (AESV2).
+Decrypt an ciphered buffer (AESV2).
@item Success condition
-Returns PDF_OK and the length of output buffer is zero.
+The output data should be correct.
@end table
@end deffn
@@ -6234,6 +6220,22 @@
@end table
@end deffn
address@hidden Test pdf_crypt_cipher_decrypt_003
address@hidden @strong
+Decrypt an ciphered buffer (AESV2).
address@hidden Success condition
+The output data should be correct.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_crypt_cipher_decrypt_004
address@hidden @strong
+Decrypt an ciphered buffer incrementally (AESV2).
address@hidden Success condition
+The output data should be correct.
address@hidden table
address@hidden deffn
+
@node pdf_crypt_md_new
@subsubsection pdf_crypt_md_new
@@ -6247,10 +6249,22 @@
@end deffn
address@hidden pdf_crypt_md_hash
address@hidden pdf_crypt_md_hash
-
address@hidden Test pdf_crypt_md_hash_001
address@hidden pdf_crypt_md_write
address@hidden pdf_crypt_md_write
+
address@hidden Test pdf_crypt_md_write_001
address@hidden @strong
+Pass an empty message.
address@hidden Success condition
+Returns PDF_OK.
address@hidden table
address@hidden deffn
+
+
address@hidden pdf_crypt_md_read
address@hidden pdf_crypt_md_read
+
address@hidden Test pdf_crypt_md_read_001
@table @strong
Compute the md5 of an empty buffer.
@item Success condition
@@ -6258,6 +6272,23 @@
@end table
@end deffn
address@hidden Test pdf_crypt_md_read_002
address@hidden @strong
+Compute the md5 checksum of a string.
address@hidden Success condition
+The output data should be correct.
address@hidden table
address@hidden deffn
+
address@hidden Test pdf_crypt_md_read_003
address@hidden @strong
+Compute the md5 checksum of a string.
address@hidden Success condition
+The output data should be correct.
address@hidden table
address@hidden deffn
+
+
@node pdf_crypt_md_destroy
@subsubsection pdf_crypt_md_destroy
=== modified file 'doc/gnupdf.texi'
--- doc/gnupdf.texi 2008-12-01 23:55:12 +0000
+++ doc/gnupdf.texi 2008-12-25 15:49:31 +0000
@@ -307,6 +307,8 @@
*p = 666;
@end example
@end table
+
+
@end deftypefun
@deftypefun void pdf_dealloc (const void address@hidden)
@@ -3436,6 +3438,16 @@
Flate (zlib) decoder.
@item PDF_STM_FILTER_JBIG2_DEC
JBIG2 decoder.
address@hidden PDF_STM_FILTER_AESV2_ENC
+AESV2 encoder.
address@hidden PDF_STM_FILTER_AESV2_DEC
+AESV2 decoder.
address@hidden PDF_STM_FILTER_V2_ENC
+V2 encoder.
address@hidden PDF_STM_FILTER_V2_ENC
+V2 decoder.
address@hidden PDF_STM_FILTER_MD5_ENC
+MD5 encoder.
@end table
@end deftp
@@ -8130,7 +8142,7 @@
@table @code
@item PDF_OK
The operation was successfully performed and the current position in
address@hidden was set to @var{pos}.
address@hidden was set to @var{pos}.
@end table
This callback is called by the @code{pdf_fsys_file_set_pos} file
@@ -8338,7 +8350,8 @@
* Initializating the module::
* Creating and destroying Ciphers::
* Encryption and decryption::
-* Message digest functions::
+* Message digest functions::
+* Utilities::
@end menu
@node Initializating the module
@@ -8376,6 +8389,7 @@
@end table
@end deftypefun
+
@node Creating and destroying Ciphers
@subsection Creating and destroying Ciphers
@@ -8507,67 +8521,6 @@
@end table
@end deftypefun
address@hidden pdf_size_t pdf_crypt_cipher_encrypt_size (pdf_crypt_cipher_t @var{cipher}, pdf_char_t address@hidden, pdf_size_t @var{in_size})
-
-Compute the size for the output buffer in
address@hidden function for the given parameters.
-
address@hidden @strong
address@hidden Parameters
address@hidden @var
address@hidden cipher
-A cipher.
address@hidden in
-A pointer to the buffer which will be encrypted.
address@hidden in_size
-The length of the buffer in bytes.
address@hidden table
address@hidden Returns
-The size of a valid output buffer in @code{pdf_crypt_cipher_encrypt}
-function for this parameters.
address@hidden Usage example
address@hidden
-pdf_crypt_cipher_t cipher;
-pdf_size_t size;
-pdf_char_t in[16];
-
-/* ...prepare the cipher... */
-size = pdf_crypt_cipher_encrypt_size (cipher, in, sizeof (in));
address@hidden example
address@hidden table
address@hidden deftypefun
-
address@hidden pdf_size_t pdf_crypt_cipher_decrypt_size (pdf_crypt_cipher_t @var{cipher}, pdf_char_t address@hidden, pdf_size_t @var{in_size})
-
-Compute the size for a valid output buffer in
address@hidden function for the given parameters.
-
address@hidden @strong
address@hidden Parameters
address@hidden @var
address@hidden cipher
-A cipher.
address@hidden in
-A pointer to the buffer which will be decrypted.
address@hidden in_size
-The length of the buffer in bytes.
address@hidden table
address@hidden Returns
-The size of a valid output buffer in @code{pdf_crypt_cipher_encrypt}
-function for this parameters.
address@hidden Usage example
address@hidden
-pdf_crypt_cipher_t cipher;
-pdf_size_t size;
-pdf_char_t *in;
-pdf_size_t in_size;
-
-/* ...prepare the cipher... */
-size = pdf_crypt_cipher_decrypt_size (cipher, in, in_size);
address@hidden example
address@hidden table
address@hidden deftypefun
-
@deftypefun pdf_status_t pdf_crypt_cipher_encrypt (pdf_crypt_cipher_t @var{cipher}, pdf_char_t address@hidden, pdf_size_t @var{out_size}, pdf_char_t address@hidden, pdf_size_t @var{in_size}, pdf_size_t address@hidden)
@@ -8586,7 +8539,9 @@
@item in
A pointer to input buffer.
@item in_size
-The length of the input buffer in bytes. I must be greater than zero.
+The length of the input buffer in bytes. I must be greater than
+zero. Some algorithms requires than IN_SIZE to be multiple of a fixed
+integer.
@item result_size
A pointer where it will put the real size of the output buffer. This
size will be lesser or equal than out_size.
@@ -8693,7 +8648,7 @@
address@hidden pdf_status_t pdf_crypt_md_new (pdf_crypt_md_t address@hidden, enum pdf_crypt_md_algo_e @var{algo})
address@hidden pdf_status_t pdf_crypt_md_new (enum pdf_crypt_md_algo_e @var{algo}, pdf_crypt_md_t address@hidden)
Create a message-digest descriptor for an algorithm.
@@ -8730,19 +8685,15 @@
address@hidden pdf_status_t pdf_crypt_md_hash (pdf_crypt_md_t @var{md}, pdf_char_t address@hidden, pdf_size_t @var{out_size}, pdf_char_t address@hidden, pdf_size_t @var{in_size})
address@hidden pdf_status_t pdf_crypt_md_write (pdf_crypt_md_t @var{md}, pdf_char_t address@hidden, pdf_size_t @var{in_size})
-Compute the message-digest for a given buffer.
+Pass a buffer to the message-digest handler in order to compute its digest.
@table @strong
@item Parameters
@table @var
@item md
A message-digest descriptor.
address@hidden out
-A pointer to output buffer.
address@hidden out_size
-The size of output buffer in bytes.
@item in
A pointer to the input buffer.
@item in_size
@@ -8759,7 +8710,6 @@
@item Usage example
@example
pdf_crypt_md_t md;
-pdf_char_t out[16];
pdf_char_t *in;
pdf_size_t in_size;
pdf_status_t st;
@@ -8768,17 +8718,61 @@
pdf_crypt_md_new (&md, PDF_CRYPT_MD_MD5);
-st = pdf_crypt_md_hash (md, out, sizeof(out), in, in_size);
-
-if (st != PDF_OK)
address@hidden
- /* Error */
address@hidden
-
-pdf_crypt_md_destroy (md);
address@hidden example
address@hidden table
address@hidden deftypefun
+st = pdf_crypt_md_hash (md, in, in_size);
+
+if (st != PDF_OK)
address@hidden
+ /* Error */
address@hidden
+
+pdf_crypt_md_destroy (md);
address@hidden example
address@hidden table
address@hidden deftypefun
+
+
+
address@hidden pdf_status_t pdf_crypt_md_read (pdf_crypt_md_t @var{md}, pdf_char_t address@hidden, pdf_size_t @var{out_size})
+
+Read the computed digest value from a message-digest descriptor.
+
address@hidden @strong
address@hidden Parameters
address@hidden @var
address@hidden md
+A message-digest descriptor.
address@hidden table
address@hidden Returns
+A PDF status value:
address@hidden @code
address@hidden PDF_OK
+Operation successful
address@hidden PDF_EBADDATA
+Bad parameter. The size of the output buffer is wrong.
address@hidden table
address@hidden Usage example
address@hidden
+pdf_crypt_md_t md;
+pdf_char_t *out;
+pdf_size_t out_size;
+pdf_status_t st;
+
+pdf_crypt_md_new (&md, PDF_CRYPT_MD_MD5);
+
+/* ...Write the buffer into descriptor here... */
+
+st = pdf_crypt_md_read (md, out, out_size);
+
+if (st != PDF_OK)
address@hidden
+ /* Error */
address@hidden
+
+pdf_crypt_md_destroy (md);
address@hidden example
address@hidden table
address@hidden deftypefun
+
@deftypefun pdf_status_t pdf_crypt_md_destroy (pdf_crypt_md_t @var{md})
@@ -8814,6 +8808,36 @@
@end deftypefun
address@hidden Utilities
address@hidden Utilities
+
address@hidden pdf_status_t pdf_crypt_nonce (pdf_crypt_char_t address@hidden, pdf_size_t @var{size})
+
+Fill a buffer with random bytes.
+
address@hidden @strong
address@hidden Parameters
address@hidden @var
address@hidden buffer
+Buffer which be filled.
address@hidden size
+Size of the buffer in bytes.
address@hidden table
address@hidden Returns
+A PDF status value:
address@hidden @code
address@hidden PDF_OK
+Operation successful
address@hidden table
address@hidden Usage example
address@hidden
+pdf_char_t buffer[16];
+
+pdf_crypt_nonce (buffer, sizeof(buffer));
address@hidden example
address@hidden table
address@hidden deftypefun
+
@node Object Layer
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2008-11-30 20:15:05 +0000
+++ src/Makefile.am 2008-12-25 15:49:31 +0000
@@ -44,7 +44,10 @@
base/pdf-stm-filter.h base/pdf-stm-filter.c \
base/pdf-stm-f-null.h base/pdf-stm-f-null.c \
base/pdf-stm-f-ahex.h base/pdf-stm-f-ahex.c \
- base/pdf-stm-f-rl.h base/pdf-stm-f-rl.c
+ base/pdf-stm-f-rl.h base/pdf-stm-f-rl.c \
+ base/pdf-stm-f-v2.h base/pdf-stm-f-v2.c \
+ base/pdf-stm-f-aesv2.h base/pdf-stm-f-aesv2.c \
+ base/pdf-stm-f-md5.h base/pdf-stm-f-md5.c
if ZLIB
STM_MODULE_SOURCES += base/pdf-stm-f-flate.c base/pdf-stm-f-flate.h
=== modified file 'src/base/MANIFEST.wiki'
--- src/base/MANIFEST.wiki 2008-11-26 21:53:10 +0000
+++ src/base/MANIFEST.wiki 2008-12-21 17:39:51 +0000
@@ -16,6 +16,9 @@
; '''pdf-stm-f-null.h''', '''pdf-stm-f-null.c'''
; '''pdf-stm-f-pred.h''', '''pdf-stm-f-pred.c'''
; '''pdf-stm-f-rl.h''', '''pdf-stm-f-rl.c'''
+; '''pdf-stm-f-aesv2.h''', '''pdf-stm-f-aesv2.c'''
+; '''pdf-stm-f-v2.h''', '''pdf-stm-f-v2.c'''
+; '''pdf-stm-f-md.h''', '''pdf-stm-f-md.c'''
: [[PDF:Standard_Filters|Implementation of the PDF standard filters]].
; '''pdf-stm-file.h''', '''pdf-stm-file.c'''
=== modified file 'src/base/pdf-crypt-c-aesv2.c'
--- src/base/pdf-crypt-c-aesv2.c 2008-11-29 16:21:37 +0000
+++ src/base/pdf-crypt-c-aesv2.c 2008-12-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 15:58:15 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 18:47:26 davazp"
*
* File: pdf-crypt.c
* Date: Fri Feb 22 21:05:05 2008
@@ -32,38 +32,49 @@
#include
#include
+
#define AESV2_BLKSIZE 16 /* Size of a block in AES128 */
+struct aesv2_state_s
+{
+ gcry_cipher_hd_t cipher;
+ pdf_bool_t first_block;
+};
+
+typedef struct aesv2_state_s * aesv2_state_t;
+
+
/* Creation and destruction of aesv2 ciphers */
pdf_status_t
-pdf_crypt_cipher_aesv2_new (void ** cipher)
+pdf_crypt_cipher_aesv2_new (void ** out)
{
- gcry_cipher_hd_t * hd;
-
- hd = pdf_alloc (sizeof (gcry_cipher_hd_t));
-
- if (hd != NULL)
+ aesv2_state_t state;
+
+ state = pdf_alloc (sizeof(struct aesv2_state_s));
+
+ if (state != NULL)
{
gcry_error_t err;
- err = gcry_cipher_open (hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
-
+ err = gcry_cipher_open (&state->cipher, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0);
+ state->first_block = PDF_TRUE;
+
if (err == GPG_ERR_NO_ERROR)
{
- *cipher = hd;
+ *out = state;
return PDF_OK;
}
else
{
- pdf_dealloc (hd);
+ pdf_dealloc (state);
return PDF_ERROR;
}
}
else
{
- pdf_dealloc (hd);
+ pdf_dealloc (state);
return PDF_ENOMEM;
}
@@ -73,11 +84,11 @@
pdf_status_t
-pdf_crypt_cipher_aesv2_destroy (void * cipher)
+pdf_crypt_cipher_aesv2_destroy (void * _state)
{
- gcry_cipher_hd_t * hd = cipher;
- gcry_cipher_close (*hd);
- pdf_dealloc (cipher);
+ aesv2_state_t state = _state;
+ gcry_cipher_close (state->cipher);
+ pdf_dealloc (state);
return PDF_OK;
}
@@ -86,12 +97,12 @@
/* Encryption and decryption functions */
pdf_status_t
-pdf_crypt_cipher_aesv2_setkey (void * cipher,
+pdf_crypt_cipher_aesv2_setkey (void * _state,
pdf_char_t *key, pdf_size_t size)
{
- gcry_cipher_hd_t * hd = cipher;
+ aesv2_state_t state = _state;
- if (gcry_cipher_setkey (*hd, key, size) == GPG_ERR_NO_ERROR)
+ if (gcry_cipher_setkey (state->cipher, key, size) == GPG_ERR_NO_ERROR)
return PDF_OK;
else
return PDF_EBADDATA;
@@ -99,101 +110,115 @@
-pdf_size_t
-pdf_crypt_cipher_aesv2_encrypt_size (void * cipher,
- pdf_char_t *in, pdf_size_t in_size)
-{
- return in_size + 2*AESV2_BLKSIZE - (in_size % AESV2_BLKSIZE);
-}
-
-
-
-pdf_size_t
-pdf_crypt_cipher_aesv2_decrypt_size (void * cipher,
- pdf_char_t *in, pdf_size_t in_size)
-{
- if (in_size < 2*AESV2_BLKSIZE)
- {
- PDF_DEBUG_BASE ("Invalid input buffer size");
- return 0;
- }
- else
- {
- return in_size <= 2*AESV2_BLKSIZE ? 0: in_size - 2*AESV2_BLKSIZE;
- }
-}
-
-
-
-pdf_status_t
-pdf_crypt_cipher_aesv2_encrypt (void * cipher,
- pdf_char_t *out, pdf_size_t out_size,
- pdf_char_t *in, pdf_size_t in_size,
- pdf_size_t *result_size)
-{
- gcry_cipher_hd_t * hd = cipher;
- pdf_size_t buffer_size;
- pdf_size_t iv_size = AESV2_BLKSIZE;
- pdf_size_t content_size = in_size;
- pdf_size_t padding_size;
- pdf_char_t * buffer = out;
- pdf_char_t * iv = &buffer[0];
- pdf_char_t * content = &buffer[iv_size];
- pdf_char_t * padding = &buffer[iv_size + content_size];
-
- buffer_size = pdf_crypt_cipher_aesv2_encrypt_size (cipher, in, in_size);
-
- if (out_size < buffer_size)
- return PDF_ERROR;
-
- padding_size = buffer_size - iv_size - content_size;
-
- gcry_create_nonce (iv, iv_size);
- memcpy (content, in, in_size);
- memset (padding, padding_size, padding_size);
-
- gcry_cipher_setiv (*hd, iv, iv_size);
- if (gcry_cipher_encrypt (*hd, content, content_size + padding_size, NULL, 0) != GPG_ERR_NO_ERROR)
- {
- return PDF_ERROR;
- }
-
- *result_size = buffer_size;
-
- return PDF_OK;
-}
-
-
-
-pdf_status_t
-pdf_crypt_cipher_aesv2_decrypt (void * cipher,
- pdf_char_t *out, pdf_size_t out_size,
- pdf_char_t *in, pdf_size_t in_size,
- pdf_size_t *result_size)
-{
- gcry_cipher_hd_t * hd = cipher;
- pdf_size_t buffer_size = in_size;
- pdf_size_t iv_size = AESV2_BLKSIZE;
- pdf_size_t content_size;
- pdf_size_t padding_size;
- pdf_char_t * buffer = in;
- pdf_char_t * iv = &buffer[0];
- pdf_char_t * content = &buffer[iv_size];
-
- gcry_cipher_setiv (*hd, iv, iv_size);
- if (gcry_cipher_decrypt (*hd, content, buffer_size - iv_size, NULL, 0) != GPG_ERR_NO_ERROR)
- {
- return PDF_ERROR;
- }
-
- padding_size = content[buffer_size - iv_size - 1];
- content_size = buffer_size - iv_size - padding_size;
-
- memcpy (out, content, content_size);
-
- *result_size = content_size;
-
- return PDF_OK;
-}
+pdf_status_t
+pdf_crypt_cipher_aesv2_encrypt (void * _state,
+ pdf_char_t *out, pdf_size_t out_size,
+ pdf_char_t *in, pdf_size_t in_size,
+ pdf_size_t *result_size)
+{
+ aesv2_state_t state = _state;
+ pdf_char_t * output;
+ pdf_size_t output_size;
+ pdf_char_t * input;
+ pdf_size_t input_size;
+
+ if (in_size < AESV2_BLKSIZE || in_size % AESV2_BLKSIZE != 0)
+ return PDF_EBADDATA;
+
+ if (out_size < in_size)
+ return PDF_EBADDATA;
+
+ /* If we are at first block, then we have found the IV vector */
+ if (state->first_block == PDF_TRUE)
+ {
+ pdf_char_t * iv = in;
+ gcry_cipher_setiv (state->cipher, iv, AESV2_BLKSIZE);
+ input = in + AESV2_BLKSIZE;
+ input_size = in_size - AESV2_BLKSIZE;
+
+ memcpy (out, iv, AESV2_BLKSIZE);
+
+ output = out + AESV2_BLKSIZE;
+ output_size = out_size - AESV2_BLKSIZE;
+
+ state->first_block = PDF_FALSE;
+ }
+ else
+ {
+ output = out;
+ output_size = out_size;
+ input = in;
+ input_size = in_size;
+ }
+
+ if (gcry_cipher_encrypt (state->cipher, output, output_size, input, input_size) != GPG_ERR_NO_ERROR)
+ {
+ return PDF_ERROR;
+ }
+
+ if (result_size != NULL)
+ *result_size = in_size;
+
+ return PDF_OK;
+}
+
+
+
+
+pdf_status_t
+pdf_crypt_cipher_aesv2_decrypt (void * _state,
+ pdf_char_t *out, pdf_size_t out_size,
+ pdf_char_t *in, pdf_size_t in_size,
+ pdf_size_t *result_size)
+{
+ aesv2_state_t state = _state;
+ pdf_char_t * output;
+ pdf_size_t output_size;
+ pdf_char_t * input;
+ pdf_size_t input_size;
+
+ if (in_size < AESV2_BLKSIZE || in_size % AESV2_BLKSIZE != 0)
+ return PDF_EBADDATA;
+
+ if (out_size < in_size)
+ return PDF_EBADDATA;
+
+ /* If we are at first block, then we have found the IV vector */
+ if (state->first_block == PDF_TRUE)
+ {
+ pdf_char_t * iv = in;
+ gcry_cipher_setiv (state->cipher, iv, AESV2_BLKSIZE);
+ input = in + AESV2_BLKSIZE;
+ input_size = in_size - AESV2_BLKSIZE;
+
+ memcpy (out, iv, AESV2_BLKSIZE);
+
+ output = out + AESV2_BLKSIZE;
+ output_size = out_size - AESV2_BLKSIZE;
+
+ state->first_block = PDF_FALSE;
+ }
+ else
+ {
+ output = out;
+ output_size = out_size;
+ input = in;
+ input_size = in_size;
+ }
+
+ if (gcry_cipher_decrypt (state->cipher, output, output_size, input, input_size) != GPG_ERR_NO_ERROR)
+ {
+ return PDF_ERROR;
+ }
+
+ if (result_size != NULL)
+ *result_size = in_size;
+
+ return PDF_OK;
+}
+
+
+
+
/* End of pdf-crypt-c-aesv2.c */
=== modified file 'src/base/pdf-crypt-c-v2.c'
--- src/base/pdf-crypt-c-v2.c 2008-11-29 16:21:37 +0000
+++ src/base/pdf-crypt-c-v2.c 2008-12-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 16:00:51 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 18:02:38 davazp"
*
* File: pdf-crypt.c
* Date: Fri Feb 22 21:05:05 2008
@@ -97,24 +97,6 @@
}
-
-pdf_size_t
-pdf_crypt_cipher_v2_encrypt_size (void * cipher,
- pdf_char_t *in, pdf_size_t in_size)
-{
- return in_size;
-}
-
-
-pdf_size_t
-pdf_crypt_cipher_v2_decrypt_size (void * cipher,
- pdf_char_t *in, pdf_size_t in_size)
-{
- return in_size;
-}
-
-
-
pdf_status_t
pdf_crypt_cipher_v2_encrypt (void * cipher,
pdf_char_t *out, pdf_size_t out_size,
@@ -125,7 +107,8 @@
if (gcry_cipher_encrypt (*hd, out, out_size, in, in_size) == GPG_ERR_NO_ERROR)
{
- *result_size = in_size;
+ if (result_size != NULL)
+ *result_size = in_size;
return PDF_OK;
}
else
@@ -146,7 +129,8 @@
if (gcry_cipher_decrypt (*hd, out, out_size, in, in_size) == GPG_ERR_NO_ERROR)
{
- *result_size = in_size;
+ if (result_size != NULL)
+ *result_size = in_size;
return PDF_OK;
}
else
=== modified file 'src/base/pdf-crypt.h'
--- src/base/pdf-crypt.h 2008-11-29 16:21:37 +0000
+++ src/base/pdf-crypt.h 2008-12-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 16:01:38 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 17:13:24 davazp"
*
* File: pdf-crypt.c
* Date: Fri Feb 22 21:05:05 2008
@@ -32,7 +32,7 @@
#include
#include
#include
-
+#include
/* BEGIN PUBLIC */
@@ -59,10 +59,6 @@
pdf_status_t (*setkey) (void * cipher, pdf_char_t *key, pdf_size_t size);
- pdf_size_t (*encrypt_size) (void * cipher, pdf_char_t *in, pdf_size_t in_size);
-
- pdf_size_t (*decrypt_size) (void * cipher, pdf_char_t *in, pdf_size_t in_size);
-
pdf_status_t (*encrypt) (void * cipher,
pdf_char_t *out, pdf_size_t out_size,
pdf_char_t *in, pdf_size_t in_size,
@@ -81,8 +77,6 @@
struct pdf_crypt_cipher_s
{
pdf_crypt_cipher_algo_t algo;
- pdf_char_t * key;
- pdf_size_t key_size;
void * raw;
};
@@ -99,6 +93,8 @@
pdf_status_t pdf_crypt_init (void);
+pdf_status_t pdf_crypt_nonce (pdf_char_t * buffer, pdf_size_t size);
+
pdf_status_t pdf_crypt_cipher_new (enum pdf_crypt_cipher_algo_e algorithm,
pdf_crypt_cipher_t *cipher);
@@ -106,12 +102,6 @@
pdf_char_t *key,
pdf_size_t size);
-pdf_size_t pdf_crypt_cipher_encrypt_size (pdf_crypt_cipher_t cipher,
- pdf_char_t *in, pdf_size_t in_size);
-
-pdf_size_t pdf_crypt_cipher_decrypt_size (pdf_crypt_cipher_t cipher,
- pdf_char_t *in, pdf_size_t in_size);
-
pdf_status_t pdf_crypt_cipher_encrypt (pdf_crypt_cipher_t cipher,
pdf_char_t *out,
pdf_size_t out_size,
@@ -129,11 +119,14 @@
pdf_status_t pdf_crypt_cipher_destroy (pdf_crypt_cipher_t cipher);
-pdf_status_t pdf_crypt_md_new (pdf_crypt_md_t *md, enum pdf_crypt_md_algo_e algo);
-
-pdf_status_t pdf_crypt_md_hash (pdf_crypt_md_t md,
- pdf_char_t *out, pdf_size_t out_size,
- pdf_char_t *in, pdf_size_t in_size);
+pdf_status_t pdf_crypt_md_new (enum pdf_crypt_md_algo_e algo, pdf_crypt_md_t *md);
+
+pdf_status_t pdf_crypt_md_write (pdf_crypt_md_t md,
+ pdf_char_t *in, pdf_size_t in_size);
+
+pdf_status_t pdf_crypt_md_read (pdf_crypt_md_t md,
+ pdf_char_t *out, pdf_size_t out_size);
+
pdf_status_t pdf_crypt_md_destroy (pdf_crypt_md_t hd);
@@ -191,6 +184,15 @@
EXTERN_INLINE pdf_status_t
+pdf_crypt_nonce (pdf_char_t * buffer, pdf_size_t size)
+{
+ gcry_create_nonce (buffer, size);
+ return PDF_OK;
+}
+
+
+
+EXTERN_INLINE pdf_status_t
pdf_crypt_cipher_new (enum pdf_crypt_cipher_algo_e algorithm,
pdf_crypt_cipher_t *cipher)
{
@@ -206,8 +208,6 @@
{
cipher_algo->new = pdf_crypt_cipher_aesv2_new;
cipher_algo->setkey = pdf_crypt_cipher_aesv2_setkey;
- cipher_algo->encrypt_size = pdf_crypt_cipher_aesv2_encrypt_size;
- cipher_algo->decrypt_size = pdf_crypt_cipher_aesv2_decrypt_size;
cipher_algo->encrypt = pdf_crypt_cipher_aesv2_encrypt;
cipher_algo->decrypt = pdf_crypt_cipher_aesv2_decrypt;
cipher_algo->destroy = pdf_crypt_cipher_aesv2_destroy;
@@ -217,8 +217,6 @@
{
cipher_algo->new = pdf_crypt_cipher_v2_new;
cipher_algo->setkey = pdf_crypt_cipher_v2_setkey;
- cipher_algo->encrypt_size = pdf_crypt_cipher_v2_encrypt_size;
- cipher_algo->decrypt_size = pdf_crypt_cipher_v2_decrypt_size;
cipher_algo->encrypt = pdf_crypt_cipher_v2_encrypt;
cipher_algo->decrypt = pdf_crypt_cipher_v2_decrypt;
cipher_algo->destroy = pdf_crypt_cipher_v2_destroy;
@@ -234,10 +232,8 @@
if (cipher_algo->new (&(*cipher)->raw) == PDF_OK)
{
- (*cipher)->algo = cipher_algo;
- (*cipher)->key = NULL;
- (*cipher)->key_size = 0;
- status = PDF_OK;
+ (*cipher)->algo = cipher_algo;
+ status = PDF_OK;
}
else
status = PDF_ERROR;
@@ -250,34 +246,7 @@
pdf_crypt_cipher_setkey (pdf_crypt_cipher_t cipher,
pdf_char_t *key, pdf_size_t size)
{
- pdf_status_t status;
-
- status = cipher->algo->setkey (cipher->raw, key, size);
-
- if (status == PDF_OK)
- {
- cipher->key = pdf_alloc (size);
- cipher->key_size = size;
- memcpy (cipher->key, key, size);
- }
-
- return status;
-}
-
-
-EXTERN_INLINE pdf_size_t
-pdf_crypt_cipher_encrypt_size (pdf_crypt_cipher_t cipher,
- pdf_char_t *in, pdf_size_t in_size)
-{
- return cipher->algo->encrypt_size (cipher->raw, in, in_size);
-}
-
-
-EXTERN_INLINE pdf_size_t
-pdf_crypt_cipher_decrypt_size (pdf_crypt_cipher_t cipher,
- pdf_char_t *in, pdf_size_t in_size)
-{
- return cipher->algo->decrypt_size (cipher->raw, in, in_size);
+ return cipher->algo->setkey (cipher->raw, key, size);
}
@@ -287,7 +256,6 @@
pdf_char_t *in, pdf_size_t in_size,
pdf_size_t *result_size)
{
- cipher->algo->setkey (cipher->raw, cipher->key, cipher->key_size);
return cipher->algo->encrypt (cipher->raw, out, out_size, in, in_size, result_size);
}
@@ -298,7 +266,6 @@
pdf_char_t *in, pdf_size_t in_size,
pdf_size_t *result_size)
{
- cipher->algo->setkey (cipher->raw, cipher->key, cipher->key_size);
return cipher->algo->decrypt (cipher->raw, out, out_size, in, in_size, result_size);
}
@@ -308,11 +275,9 @@
{
pdf_status_t ret;
- pdf_dealloc (cipher->key);
ret = cipher->algo->destroy (cipher->raw);
pdf_dealloc (cipher->algo);
pdf_dealloc (cipher);
-
return ret;
}
@@ -321,58 +286,84 @@
EXTERN_INLINE pdf_status_t
-pdf_crypt_md_new (pdf_crypt_md_t *md, enum pdf_crypt_md_algo_e algo)
+pdf_crypt_md_new (enum pdf_crypt_md_algo_e algo, pdf_crypt_md_t *_md)
{
- *md = pdf_alloc (sizeof(struct pdf_crypt_md_s));
+ pdf_crypt_md_t md;
+ gcry_md_hd_t * raw;
+ pdf_status_t ret;
+
+ md = pdf_alloc (sizeof(struct pdf_crypt_md_s));
if (algo == PDF_CRYPT_MD_MD5)
{
- (*md)->raw = pdf_alloc (sizeof(gcry_md_hd_t));
+ raw = pdf_alloc (sizeof(gcry_md_hd_t));
- if (gcry_md_open ((*md)->raw, GCRY_MD_MD5, 0) == GPG_ERR_NO_ERROR)
- {
- return PDF_OK;
- }
+ if (gcry_md_open (raw, GCRY_MD_MD5, 0) == GPG_ERR_NO_ERROR)
+ {
+ md->raw = raw;
+ *_md = md;
+ ret = PDF_OK;
+ }
else
- {
- pdf_dealloc ((*md)->raw);
- return PDF_ERROR;
- }
+ {
+ gcry_md_close (*raw);
+ ret = PDF_ERROR;
+ }
}
else
{
- return PDF_EBADDATA;
+ ret = PDF_EBADDATA;
}
+
+ return ret;
}
EXTERN_INLINE pdf_status_t
-pdf_crypt_md_hash (pdf_crypt_md_t md,
- pdf_char_t *out, pdf_size_t out_size,
- pdf_char_t *in, pdf_size_t in_size)
+pdf_crypt_md_write (pdf_crypt_md_t md,
+ pdf_char_t *in, pdf_size_t in_size)
{
gcry_md_hd_t * gcry_md = md->raw;
- register pdf_size_t i;
-
- for (i = 0; i < in_size; i++)
- {
- gcry_md_putc (*gcry_md, in[i]);
- }
-
+ gcry_md_write (*gcry_md, in, in_size);
+ return PDF_OK;
+}
+
+
+EXTERN_INLINE pdf_status_t
+pdf_crypt_md_read (pdf_crypt_md_t md,
+ pdf_char_t *out, pdf_size_t out_size)
+{
+ gcry_md_hd_t * gcry_md = md->raw;
+ pdf_size_t required_size = gcry_md_get_algo_dlen (GCRY_MD_MD5);
+
+ if (out_size < required_size)
+ return PDF_EBADDATA;
+
if (gcry_md_final (*gcry_md) != GPG_ERR_NO_ERROR)
{
return PDF_ERROR;
}
else
{
- gcry_md_read (*gcry_md, GCRY_MD_MD5);
- gcry_md_close (*gcry_md);
+ void * hash;
+
+ hash = gcry_md_read (*gcry_md, GCRY_MD_MD5);
+
+ if (hash == NULL)
+ return PDF_ERROR;
+ else
+ {
+ memcpy (out, hash, required_size);
+ }
+
+ gcry_md_reset (*gcry_md);
return PDF_OK;
}
}
+
EXTERN_INLINE pdf_status_t
pdf_crypt_md_destroy (pdf_crypt_md_t md)
{
=== modified file 'src/base/pdf-stm-buffer.c'
--- src/base/pdf-stm-buffer.c 2008-10-04 12:31:11 +0000
+++ src/base/pdf-stm-buffer.c 2008-12-21 17:39:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/10/04 14:26:53 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-20 15:48:31 davazp"
*
* File: pdf-stm-buffer.c
* Date: Wed Jul 23 23:28:59 2008
@@ -25,6 +25,7 @@
#include
#include
+#include
pdf_stm_buffer_t
pdf_stm_buffer_new (pdf_size_t size)
@@ -64,6 +65,20 @@
return ((buffer->wp - buffer->rp) == 0);
}
+
+pdf_status_t
+pdf_stm_buffer_resize (pdf_stm_buffer_t buffer, pdf_size_t newsize)
+{
+ if (pdf_realloc (buffer->data, newsize) != PDF_OK)
+ return PDF_ENOMEM;
+
+ buffer->size = newsize;
+ buffer->rp = PDF_MIN (buffer->rp, newsize);
+ buffer->wp = PDF_MIN (buffer->wp, newsize);
+ return PDF_OK;
+}
+
+
pdf_status_t
pdf_stm_buffer_rewind (pdf_stm_buffer_t buffer)
{
=== modified file 'src/base/pdf-stm-buffer.h'
--- src/base/pdf-stm-buffer.h 2008-11-29 16:21:37 +0000
+++ src/base/pdf-stm-buffer.h 2008-12-21 17:39:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 15:14:38 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-20 15:48:34 davazp"
*
* File: pdf-stm-buffer.h
* Date: Wed Jun 18 20:34:23 2008
@@ -49,6 +49,7 @@
pdf_bool_t pdf_stm_buffer_full_p (pdf_stm_buffer_t buffer);
pdf_bool_t pdf_stm_buffer_eob_p (pdf_stm_buffer_t buffer);
+pdf_status_t pdf_stm_buffer_resize (pdf_stm_buffer_t buffer, pdf_size_t newsize);
pdf_status_t pdf_stm_buffer_rewind (pdf_stm_buffer_t buffer);
#endif /* !PDF_STM_BUFFER_H */
=== added file 'src/base/pdf-stm-f-aesv2.c'
--- src/base/pdf-stm-f-aesv2.c 1970-01-01 00:00:00 +0000
+++ src/base/pdf-stm-f-aesv2.c 2008-12-25 15:49:31 +0000
@@ -0,0 +1,333 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-25 16:37:22 davazp"
+ *
+ * File: pdf-stm-f-aesv2.c
+ * Date: Sun Dec 14 20:13:53 2008
+ *
+ * GNU PDF Library - AESV2 stream filter
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+#include
+#include
+#include
+
+#define AESV2_CACHE_SIZE 16
+
+
+/* Internal state */
+struct pdf_stm_f_aesv2_s
+{
+ pdf_crypt_cipher_t cipher;
+ pdf_stm_buffer_t in_cache;
+ pdf_stm_buffer_t out_cache;
+};
+typedef struct pdf_stm_f_aesv2_s * pdf_stm_f_aesv2_t;
+
+
+/* Encryption and decryption */
+enum pdf_stm_f_aesv2_mode_e
+ {
+ PDF_STM_F_AESV2_MODE_ENCODE,
+ PDF_STM_F_AESV2_MODE_DECODE
+ };
+typedef enum pdf_stm_f_aesv2_mode_e pdf_stm_f_aesv2_mode_t;
+
+
+
+static inline pdf_status_t
+pdf_stm_f_aesv2_init (pdf_hash_t params, void **state)
+{
+ pdf_status_t ret;
+ pdf_stm_f_aesv2_t filter_state;
+
+ filter_state = pdf_alloc (sizeof (struct pdf_stm_f_aesv2_s));
+
+ if (filter_state == NULL)
+ {
+ ret = PDF_ENOMEM;
+ }
+ else if (state == NULL)
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ else
+ {
+ pdf_char_t * key;
+ pdf_size_t * keysize;
+ pdf_crypt_cipher_t cipher;
+
+ /* We demand all parameters are present */
+ if ((( pdf_hash_key_p (params, "Key") == PDF_TRUE))
+ && pdf_hash_key_p (params, "KeySize") == PDF_TRUE)
+ {
+ pdf_hash_search (params, "Key", (const void **)&key);
+ pdf_hash_search (params, "KeySize", (const void **)&keysize);
+
+ if (pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher) == PDF_OK
+ && pdf_crypt_cipher_setkey (cipher, key, *keysize) == PDF_OK)
+ {
+ filter_state->cipher = cipher;
+
+ /* Initialize cache buffers */
+ filter_state->in_cache = pdf_stm_buffer_new (AESV2_CACHE_SIZE);
+ filter_state->out_cache = pdf_stm_buffer_new (AESV2_CACHE_SIZE);
+
+ if (filter_state->in_cache == NULL || filter_state->out_cache == NULL)
+ {
+ ret = PDF_ERROR;
+ }
+ else
+ {
+ ret = PDF_OK;
+ *state = filter_state;
+ }
+ }
+ else
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ }
+ else
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ }
+
+ return ret;
+}
+
+
+
+
+static inline pdf_status_t
+pdf_stm_f_aesv2_apply (pdf_stm_f_aesv2_mode_t mode,
+ pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ pdf_stm_f_aesv2_t filter_state = state;
+ pdf_crypt_cipher_t cipher = filter_state->cipher;
+ pdf_stm_buffer_t in_cache = filter_state->in_cache;
+ pdf_stm_buffer_t out_cache = filter_state->out_cache;
+
+ while(1)
+ {
+ pdf_size_t in_size;
+ pdf_size_t out_size;
+ pdf_size_t in_cache_size;
+ pdf_size_t out_cache_size;
+ pdf_size_t bytes_to_read;
+ pdf_size_t bytes_to_write;
+
+ /* Read bytes from IN and fill IN_CACHE*/
+ in_size = in->wp - in->rp;
+ in_cache_size = in_cache->size - in_cache->wp;
+ bytes_to_read = PDF_MIN (in_size, in_cache_size);
+
+ memcpy (in_cache->data + in_cache->wp,
+ in->data + in->rp,
+ bytes_to_read);
+
+ in_cache->wp += bytes_to_read;
+ in->rp += bytes_to_read;
+
+
+ /* If we cannot fill all IN_CACHE... */
+ if (!pdf_stm_buffer_full_p (in_cache))
+ {
+ if (finish_p && mode == PDF_STM_F_AESV2_MODE_DECODE
+ && in_cache->wp > 0)
+ return PDF_ERROR;
+
+ /* ...pad the cache if we have reached EOD */
+ if (finish_p
+ && !pdf_stm_buffer_full_p (in_cache)
+ && mode == PDF_STM_F_AESV2_MODE_ENCODE)
+ {
+ pdf_size_t padding;
+ padding = in_cache->size - in_cache->wp;
+
+ memset (in_cache->data + in_cache->wp,
+ padding,
+ padding);
+
+ in_cache->wp += padding;
+ }
+ else
+ {
+ if (pdf_stm_buffer_eob_p (out_cache))
+ return PDF_ENINPUT; /* ...ask more input */
+ }
+ }
+
+
+ /* If OUT_CACHE is empty and IN_CACHE is full, then it is ready
+ to be processed. */
+ if (pdf_stm_buffer_full_p (in_cache) && pdf_stm_buffer_eob_p (out_cache))
+ {
+ switch (mode)
+ {
+ case PDF_STM_F_AESV2_MODE_ENCODE:
+ pdf_crypt_cipher_encrypt (cipher,
+ out_cache->data,
+ out_cache->size,
+ in_cache->data,
+ in_cache->size,
+ NULL);
+ break;
+
+ case PDF_STM_F_AESV2_MODE_DECODE:
+ pdf_crypt_cipher_decrypt (cipher,
+ out_cache->data,
+ out_cache->size,
+ in_cache->data,
+ in_cache->size,
+ NULL);
+ break;
+
+ default: /* not reached */
+ break;
+ }
+
+ /* Both cache are full now */
+ pdf_stm_buffer_rewind (in_cache);
+ out_cache->wp = out_cache->size;
+ }
+
+
+ /* When we are decrypting data, we need know what block is the
+ last. If both IN and IN_CACHE are empty, then OUT_CACHE could
+ hold it. So, we ask more input to we make sure.*/
+ if (mode == PDF_STM_F_AESV2_MODE_DECODE
+ && pdf_stm_buffer_eob_p (in) && pdf_stm_buffer_eob_p (in_cache))
+ {
+ /* When we know it is the last, remove the padding. */
+ if (finish_p)
+ {
+ pdf_size_t padding;
+ padding = out_cache->data[out_cache->size - 1];
+
+ if (padding > AESV2_CACHE_SIZE)
+ return PDF_ERROR;
+
+ out_cache->wp = out_cache->size - padding;
+ }
+ else
+ return PDF_ENINPUT;
+ }
+
+
+ /* Finally, we fill the OUT buffer */
+ out_size = out->size - out->wp;
+ out_cache_size = out_cache->wp - out_cache->rp;
+ bytes_to_write = PDF_MIN (out_size, out_cache_size);
+
+ memcpy (out->data + out->wp,
+ out_cache->data + out_cache->rp,
+ bytes_to_write);
+
+ out_cache->rp += bytes_to_write;
+ out->wp += bytes_to_write;
+
+
+ if (finish_p)
+ {
+ return PDF_EEOF;
+ }
+ else if (pdf_stm_buffer_full_p (out))
+ {
+ return PDF_ENOUTPUT;
+ }
+ else
+ {
+ pdf_stm_buffer_rewind (out_cache);
+ }
+ }
+}
+
+
+
+static inline pdf_status_t
+pdf_stm_f_aesv2_dealloc_state (void *state)
+{
+ pdf_stm_f_aesv2_t filter_state = state;
+ pdf_crypt_cipher_destroy (filter_state->cipher);
+ pdf_stm_buffer_destroy (filter_state->in_cache);
+ pdf_stm_buffer_destroy (filter_state->out_cache);
+ pdf_dealloc (state);
+ return PDF_OK;
+}
+
+
+
+
+/* Encode filter */
+
+pdf_status_t
+pdf_stm_f_aesv2enc_init (pdf_hash_t params, void **state)
+{
+ return pdf_stm_f_aesv2_init (params, state);
+}
+
+pdf_status_t
+pdf_stm_f_aesv2enc_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ return pdf_stm_f_aesv2_apply (PDF_STM_F_AESV2_MODE_ENCODE,
+ params, state, in, out, finish_p);
+}
+
+pdf_status_t
+pdf_stm_f_aesv2enc_dealloc_state (void *state)
+{
+ return pdf_stm_f_aesv2_dealloc_state (state);
+}
+
+
+
+/* Decode filter */
+
+pdf_status_t
+pdf_stm_f_aesv2dec_init (pdf_hash_t params, void **state)
+{
+ return pdf_stm_f_aesv2_init (params, state);
+}
+
+
+pdf_status_t
+pdf_stm_f_aesv2dec_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ return pdf_stm_f_aesv2_apply (PDF_STM_F_AESV2_MODE_DECODE,
+ params, state, in, out, finish_p);
+}
+
+
+pdf_status_t
+pdf_stm_f_aesv2dec_dealloc_state (void *state)
+{
+ return pdf_stm_f_aesv2_dealloc_state (state);
+}
+
+
+
+/* End of pdf_stm_f_aesv2.c */
=== added file 'src/base/pdf-stm-f-aesv2.h'
--- src/base/pdf-stm-f-aesv2.h 1970-01-01 00:00:00 +0000
+++ src/base/pdf-stm-f-aesv2.h 2008-12-21 17:39:51 +0000
@@ -0,0 +1,65 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-14 20:32:40 davazp"
+ *
+ * File: pdf-stm-f-aesv2.h
+ * Date: Fri Dec 5 16:58:49 2008
+ *
+ * GNU PDF Library - AESv2 stream filter
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef PDF_STM_F_AESV2_H
+#define PDF_STM_F_AESV2_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+pdf_status_t pdf_stm_f_aesv2enc_init (pdf_hash_t params,
+ void **state);
+
+pdf_status_t pdf_stm_f_aesv2enc_apply (pdf_hash_t params,
+ void *state,
+ pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_aesv2enc_dealloc_state (void *state);
+
+
+pdf_status_t pdf_stm_f_aesv2dec_init (pdf_hash_t params,
+ void **state);
+
+pdf_status_t pdf_stm_f_aesv2dec_apply (pdf_hash_t params,
+ void *state,
+ pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_aesv2dec_dealloc_state (void *state);
+
+
+
+#endif /* PDF_STM_F_AESV2_H */
+
+/* End of pdf_stm_f_aesv2.h */
=== added file 'src/base/pdf-stm-f-md5.c'
--- src/base/pdf-stm-f-md5.c 1970-01-01 00:00:00 +0000
+++ src/base/pdf-stm-f-md5.c 2008-12-25 15:49:31 +0000
@@ -0,0 +1,151 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-25 00:13:01 davazp"
+ *
+ * File: pdf-stm-f-md5.c
+ * Date: Fri Dec 5 16:40:50 2008
+ *
+ * GNU PDF Library - Message-digest stream filter
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#define MD5_OUTPUT_SIZE 16
+
+
+
+/* Internal state */
+struct pdf_stm_f_md5_s
+{
+ pdf_crypt_md_t md;
+ pdf_stm_buffer_t cache;
+};
+typedef struct pdf_stm_f_md5_s * pdf_stm_f_md5_t;
+
+
+
+pdf_status_t
+pdf_stm_f_md5enc_init (pdf_hash_t params, void **state)
+{
+ pdf_status_t ret;
+ pdf_stm_f_md5_t filter_state;
+
+ filter_state = pdf_alloc (sizeof (struct pdf_stm_f_md5_s));
+
+ if (filter_state == NULL)
+ {
+ ret = PDF_ENOMEM;
+ }
+ else if (state == NULL)
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ else
+ {
+ pdf_crypt_md_t md;
+
+ if (pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md) == PDF_OK)
+ {
+ filter_state->md = md;
+ filter_state->cache = pdf_stm_buffer_new (MD5_OUTPUT_SIZE);
+
+ if (filter_state->cache == NULL)
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_ERROR;
+ }
+ else
+ {
+ *state = filter_state;
+ ret = PDF_OK;
+ }
+ }
+ else
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ }
+ return ret;
+}
+
+
+
+pdf_status_t
+pdf_stm_f_md5enc_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ pdf_stm_f_md5_t filter_state = state;
+ pdf_stm_buffer_t cache = filter_state->cache;
+ pdf_size_t in_size;
+ pdf_status_t ret;
+
+ in_size = in->wp - in->rp;
+
+ pdf_crypt_md_write (filter_state->md, in->data, in_size);
+ in->rp += in_size;
+ ret = PDF_ENINPUT;
+
+ if (finish_p == PDF_TRUE)
+ {
+ pdf_size_t bytes_to_write;
+ pdf_size_t cache_size;
+ pdf_size_t out_size;
+
+ if (pdf_stm_buffer_eob_p (cache))
+ {
+ /* If we have reached the end, read the hash value in cache */
+ pdf_crypt_md_read (filter_state->md, cache->data, cache->size);
+ cache->wp = cache->size;
+ }
+
+ out_size = out->size - out->wp;
+ cache_size = cache->wp - cache->rp;
+ bytes_to_write = PDF_MIN (out_size, cache_size);
+
+ memcpy (out->data, cache->data + cache->rp, bytes_to_write);
+
+ cache->rp += bytes_to_write;
+ out->wp += bytes_to_write;
+
+ if (out_size < cache_size)
+ ret = PDF_ENOUTPUT;
+ else
+ ret = PDF_EEOF;
+ }
+
+ return ret;
+}
+
+
+
+pdf_status_t
+pdf_stm_f_md5enc_dealloc_state (void *state)
+{
+ pdf_stm_f_md5_t filter_state = state;
+ pdf_crypt_md_destroy (filter_state->md);
+ pdf_stm_buffer_destroy (filter_state->cache);
+ pdf_dealloc (state);
+ return PDF_OK;
+}
+
+
+
+/* End of pdf_stm_f_md5.c */
=== added file 'src/base/pdf-stm-f-md5.h'
--- src/base/pdf-stm-f-md5.h 1970-01-01 00:00:00 +0000
+++ src/base/pdf-stm-f-md5.h 2008-12-21 17:39:51 +0000
@@ -0,0 +1,63 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-15 17:53:17 davazp"
+ *
+ * File: pdf-stm-f-md5.h
+ * Date: Fri Dec 5 16:38:39 2008
+ *
+ * GNU PDF Library - MD5 stream filter
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef PDF_STM_F_MD5_H
+#define PDF_STM_F_MD5_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Internal state of cipher filter */
+
+struct pdf_stm_f_md_s
+{
+ void *md;
+};
+
+
+/* Filter API implementation */
+
+pdf_status_t pdf_stm_f_md5enc_init (pdf_hash_t params,
+ void **state);
+
+pdf_status_t pdf_stm_f_md5enc_apply (pdf_hash_t params,
+ void *state,
+ pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_md5enc_dealloc_state (void *state);
+
+
+
+#endif /* PDF_STM_F_MD5_H */
+
+/* End of pdf_stm_f_md5.h */
=== added file 'src/base/pdf-stm-f-v2.c'
--- src/base/pdf-stm-f-v2.c 1970-01-01 00:00:00 +0000
+++ src/base/pdf-stm-f-v2.c 2008-12-25 15:49:31 +0000
@@ -0,0 +1,222 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-24 22:58:05 davazp"
+ *
+ * File: pdf-stm-f-v2.c
+ * Date: Tue Jul 10 23:44:00 2007
+ *
+ * GNU PDF Library - V2 stream filter
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+
+/* Internal state */
+struct pdf_stm_f_v2_s
+{
+ pdf_crypt_cipher_t cipher;
+};
+typedef struct pdf_stm_f_v2_s * pdf_stm_f_v2_t;
+
+
+/* Encryption and decryption */
+enum pdf_stm_f_v2_mode_e
+{
+ PDF_STM_F_V2_MODE_ENCODE,
+ PDF_STM_F_V2_MODE_DECODE
+};
+typedef enum pdf_stm_f_v2_mode_e pdf_stm_f_v2_mode_t;
+
+
+
+static inline pdf_status_t
+pdf_stm_f_v2_init (pdf_hash_t params, void **state)
+{
+ pdf_status_t ret;
+ pdf_stm_f_v2_t filter_state;
+
+ filter_state = pdf_alloc (sizeof (struct pdf_stm_f_v2_s));
+
+ if (filter_state == NULL)
+ {
+ ret = PDF_ENOMEM;
+ }
+ else if (state == NULL)
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ else
+ {
+ pdf_char_t * key;
+ pdf_size_t * keysize;
+ pdf_crypt_cipher_t cipher;
+
+ /* We demand all parameters are present */
+ if ((( pdf_hash_key_p (params, "Key") == PDF_TRUE))
+ && pdf_hash_key_p (params, "KeySize") == PDF_TRUE)
+ {
+ pdf_hash_search (params, "Key", (const void **)&key);
+ pdf_hash_search (params, "KeySize", (const void **)&keysize);
+
+ if (pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher) == PDF_OK
+ && pdf_crypt_cipher_setkey (cipher, key, *keysize) == PDF_OK)
+ {
+ filter_state->cipher = cipher;
+ *state = filter_state;
+ ret = PDF_OK;
+ }
+ else
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ }
+ else
+ {
+ pdf_dealloc (filter_state);
+ ret = PDF_EBADDATA;
+ }
+ }
+
+ return ret;
+}
+
+
+static inline pdf_status_t
+pdf_stm_f_v2_apply (pdf_stm_f_v2_mode_t mode,
+ pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ pdf_stm_f_v2_t filter_state = state;
+
+ pdf_size_t in_size;
+ pdf_size_t out_size;
+ pdf_size_t bytes_to_copy;
+ pdf_size_t written;
+ pdf_status_t ret;
+
+ in_size = in->wp - in->rp;
+ out_size = out->size - out->wp;
+
+ bytes_to_copy = PDF_MIN(out_size, in_size);
+
+ if (bytes_to_copy != 0)
+ {
+ if (mode == PDF_STM_F_V2_MODE_ENCODE)
+ {
+ pdf_crypt_cipher_encrypt (filter_state->cipher,
+ out->data,
+ out_size,
+ in->data,
+ in_size,
+ &written);
+ }
+ else if (mode == PDF_STM_F_V2_MODE_DECODE)
+ {
+ pdf_crypt_cipher_decrypt (filter_state->cipher,
+ out->data,
+ out_size,
+ in->data,
+ in_size,
+ &written);
+ }
+ else
+ {
+ /* This point should not be reached. */
+ }
+
+ in->rp += bytes_to_copy;
+ out->wp += written;
+ }
+
+ if (in_size > out_size)
+ {
+ /* We need more room in the output buffer */
+ ret = PDF_ENOUTPUT;
+ }
+ else
+ {
+ /* We can process more input */
+ ret = PDF_ENINPUT;
+ }
+
+ return ret;
+}
+
+
+static inline pdf_status_t
+pdf_stm_f_v2_dealloc_state (void *state)
+{
+ pdf_stm_f_v2_t filter_state = state;
+ pdf_crypt_cipher_destroy (filter_state->cipher);
+ pdf_dealloc (state);
+ return PDF_OK;
+}
+
+
+
+/* Encode filter */
+
+pdf_status_t
+pdf_stm_f_v2enc_init (pdf_hash_t params, void **state)
+{
+ return pdf_stm_f_v2_init (params, state);
+}
+
+pdf_status_t
+pdf_stm_f_v2enc_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ return pdf_stm_f_v2_apply (PDF_STM_F_V2_MODE_ENCODE,
+ params, state, in, out, finish_p);
+}
+
+pdf_status_t
+pdf_stm_f_v2enc_dealloc_state (void *state)
+{
+ return pdf_stm_f_v2_dealloc_state (state);
+}
+
+
+/* Decode filter */
+
+pdf_status_t
+pdf_stm_f_v2dec_init (pdf_hash_t params, void **state)
+{
+ return pdf_stm_f_v2_init (params, state);
+}
+
+
+pdf_status_t
+pdf_stm_f_v2dec_apply (pdf_hash_t params, void *state, pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out, pdf_bool_t finish_p)
+{
+ return pdf_stm_f_v2_apply (PDF_STM_F_V2_MODE_DECODE,
+ params, state, in, out, finish_p);
+}
+
+
+pdf_status_t
+pdf_stm_f_v2dec_dealloc_state (void *state)
+{
+ return pdf_stm_f_v2_dealloc_state (state);
+}
+
+
+/* End of pdf_stm_f_v2.c */
=== added file 'src/base/pdf-stm-f-v2.h'
--- src/base/pdf-stm-f-v2.h 1970-01-01 00:00:00 +0000
+++ src/base/pdf-stm-f-v2.h 2008-12-21 17:39:51 +0000
@@ -0,0 +1,67 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-14 20:16:02 davazp"
+ *
+ * File: pdf-stm-f-v2.h
+ * Date: Fri Dec 5 16:58:49 2008
+ *
+ * GNU PDF Library - V2 stream filter
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef PDF_STM_F_V2_H
+#define PDF_STM_F_V2_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Filter API implementation */
+
+pdf_status_t pdf_stm_f_v2enc_init (pdf_hash_t params,
+ void **state);
+
+pdf_status_t pdf_stm_f_v2enc_apply (pdf_hash_t params,
+ void *state,
+ pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_v2enc_dealloc_state (void *state);
+
+
+pdf_status_t pdf_stm_f_v2dec_init (pdf_hash_t params,
+ void **state);
+
+pdf_status_t pdf_stm_f_v2dec_apply (pdf_hash_t params,
+ void *state,
+ pdf_stm_buffer_t in,
+ pdf_stm_buffer_t out,
+ pdf_bool_t finish_p);
+
+pdf_status_t pdf_stm_f_v2dec_dealloc_state (void *state);
+
+
+
+#endif /* PDF_STM_F_V2_H */
+
+/* End of pdf_stm_f_v2.h */
=== modified file 'src/base/pdf-stm-filter.c'
--- src/base/pdf-stm-filter.c 2008-12-08 19:03:28 +0000
+++ src/base/pdf-stm-filter.c 2008-12-25 15:49:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/12/08 20:02:37 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-24 02:35:06 davazp"
*
* File: pdf-stm-filter.c
* Date: Thu Jun 12 22:13:31 2008
@@ -101,6 +101,7 @@
new->impl.dealloc_state_fn = pdf_stm_f_rldec_dealloc_state;
break;
}
+
#if defined(HAVE_LIBZ)
case PDF_STM_FILTER_FLATE_ENC:
{
@@ -117,6 +118,42 @@
break;
}
#endif /* HAVE_LIBZ */
+ case PDF_STM_FILTER_V2_ENC:
+ {
+ new->impl.init_fn = pdf_stm_f_v2enc_init;
+ new->impl.apply_fn = pdf_stm_f_v2enc_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_v2enc_dealloc_state;
+ break;
+ }
+ case PDF_STM_FILTER_V2_DEC:
+ {
+ new->impl.init_fn = pdf_stm_f_v2dec_init;
+ new->impl.apply_fn = pdf_stm_f_v2dec_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_v2dec_dealloc_state;
+ break;
+ }
+ case PDF_STM_FILTER_AESV2_ENC:
+ {
+ new->impl.init_fn = pdf_stm_f_aesv2enc_init;
+ new->impl.apply_fn = pdf_stm_f_aesv2enc_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_aesv2enc_dealloc_state;
+ break;
+ }
+ case PDF_STM_FILTER_AESV2_DEC:
+ {
+ new->impl.init_fn = pdf_stm_f_aesv2dec_init;
+ new->impl.apply_fn = pdf_stm_f_aesv2dec_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_aesv2dec_dealloc_state;
+ break;
+ }
+ case PDF_STM_FILTER_MD5_ENC:
+ {
+ new->impl.init_fn = pdf_stm_f_md5enc_init;
+ new->impl.apply_fn = pdf_stm_f_md5enc_apply;
+ new->impl.dealloc_state_fn = pdf_stm_f_md5enc_dealloc_state;
+ break;
+ }
+
#if defined(HAVE_JBIG2DEC)
case PDF_STM_FILTER_JBIG2_DEC:
{
@@ -126,6 +163,7 @@
break;
}
#endif /* HAVE_JBIG2DEC */
+
default:
{
/* Shall not be reached, but makes the compiler happy */
=== modified file 'src/base/pdf-stm-filter.h'
--- src/base/pdf-stm-filter.h 2008-11-29 16:21:37 +0000
+++ src/base/pdf-stm-filter.h 2008-12-25 15:49:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 15:10:34 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-24 02:35:52 davazp"
*
* File: pdf-stm-filter.h
* Date: Thu Jun 12 22:05:06 2008
@@ -35,6 +35,9 @@
#include
#include
#include
+#include
+#include
+#include
#if defined(HAVE_LIBZ)
# include
@@ -56,6 +59,11 @@
PDF_STM_FILTER_RL_DEC,
PDF_STM_FILTER_FLATE_ENC,
PDF_STM_FILTER_FLATE_DEC,
+ PDF_STM_FILTER_AESV2_ENC,
+ PDF_STM_FILTER_AESV2_DEC,
+ PDF_STM_FILTER_V2_ENC,
+ PDF_STM_FILTER_V2_DEC,
+ PDF_STM_FILTER_MD5_ENC,
PDF_STM_FILTER_JBIG2_DEC
};
=== modified file 'torture/unit/Makefile.am'
--- torture/unit/Makefile.am 2008-12-02 20:28:39 +0000
+++ torture/unit/Makefile.am 2008-12-23 18:08:31 +0000
@@ -166,13 +166,13 @@
TEST_SUITE_CRYPT = base/crypt/pdf-crypt-init.c \
base/crypt/pdf-crypt-cipher-new.c \
+ base/crypt/pdf-crypt-cipher-setkey.c \
base/crypt/pdf-crypt-cipher-destroy.c \
- base/crypt/pdf-crypt-cipher-encrypt-size.c \
- base/crypt/pdf-crypt-cipher-decrypt-size.c \
base/crypt/pdf-crypt-cipher-encrypt.c \
base/crypt/pdf-crypt-cipher-decrypt.c \
base/crypt/pdf-crypt-md-new.c \
- base/crypt/pdf-crypt-md-hash.c \
+ base/crypt/pdf-crypt-md-write.c \
+ base/crypt/pdf-crypt-md-read.c \
base/crypt/pdf-crypt-md-destroy.c
TEST_SUITE_ALLOC = base/alloc/pdf-alloc.c \
=== removed file 'torture/unit/base/crypt/pdf-crypt-cipher-decrypt-size.c'
--- torture/unit/base/crypt/pdf-crypt-cipher-decrypt-size.c 2008-10-03 16:08:19 +0000
+++ torture/unit/base/crypt/pdf-crypt-cipher-decrypt-size.c 1970-01-01 00:00:00 +0000
@@ -1,87 +0,0 @@
-/* -*- mode: C -*- Time-stamp: "08/09/20 14:43:38 jemarch"
- *
- * File: pdf-crypt-cipher-decrypt-size.c
- * Date: Wed Mar 12 12:43:00 2008
- *
- * GNU PDF Library - Unit tests for pdf_crypt_cipher_decrypt_size
- *
- */
-
-/* Copyright (C) 2008 Free Software Foundation, Inc. */
-
-/* This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-
-#include
-#include
-#include
-#include
-
-
-/*
- * Test: pdf_crypt_cipher_decrypt_size_001
- * Description:
- * Get the plain buffer size for a 32 bytes ciphered buffer (AESV2).
- * Success condition:
- * Returns 0
- */
-START_TEST (pdf_crypt_cipher_decrypt_size_001)
-{
- pdf_crypt_cipher_t cipher;
- pdf_crypt_init();
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
- fail_if (pdf_crypt_cipher_decrypt_size (cipher, NULL, 32) != 0);
- pdf_crypt_cipher_destroy (cipher);
-}
-END_TEST
-
-
-/*
- * Test: pdf_crypt_cipher_decrypt_size_003
- * Description:
- * Get the plain buffer size for a 15 bytes ciphered buffer (V2).
- * Success condition:
- * Returns 15
- */
-START_TEST (pdf_crypt_cipher_decrypt_size_002)
-{
- pdf_crypt_cipher_t cipher;
- pdf_crypt_init();
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
- fail_if (pdf_crypt_cipher_decrypt_size (cipher, NULL, 15) != 15);
- pdf_crypt_cipher_destroy (cipher);
-}
-END_TEST
-
-
-
-/*
- * Test case creation function
- */
-TCase *
-test_pdf_crypt_cipher_decrypt_size (void)
-{
- TCase *tc = tcase_create("pdf_crypt_cipher_decrypt_size");
-
- tcase_add_test(tc, pdf_crypt_cipher_decrypt_size_001);
- tcase_add_test(tc, pdf_crypt_cipher_decrypt_size_002);
-
- return tc;
-}
-
-
-/* End of pdf-crypt-cipher-decrypt-size.c */
-
=== modified file 'torture/unit/base/crypt/pdf-crypt-cipher-decrypt.c'
--- torture/unit/base/crypt/pdf-crypt-cipher-decrypt.c 2008-11-29 16:21:37 +0000
+++ torture/unit/base/crypt/pdf-crypt-cipher-decrypt.c 2008-12-23 18:08:31 +0000
@@ -1,26 +1,27 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 16:04:36 jemarch"
- *
+/*
+ * -*- mode: C -*- Time-stamp: "2008-12-23 18:57:09 davazp"
+ *
* File: pdf-crypt-cipher-decrypt.c
* Date: Wed Mar 12 12:43:00 2008
- *
+ *
* GNU PDF Library - Unit tests for pdf_crypt_cipher_decrypt
- *
- */
-
-/* Copyright (C) 2008 Free Software Foundation, Inc. */
-
-/* This program is free software: you can redistribute it and/or modify
+ *
+ *
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
+ *
*/
#include
@@ -34,57 +35,66 @@
/*
* Test: pdf_crypt_cipher_decrypt_001
* Description:
- * Decrypt an ciphered empty buffer (AESV2).
+ * Decrypt an ciphered buffer (AEV2).
* Success condition:
- * Returns 0.
+ * The ouput data should be correct.
*/
START_TEST (pdf_crypt_cipher_decrypt_001)
{
pdf_crypt_cipher_t cipher;
- pdf_char_t *plain;
- pdf_size_t plain_size;
-
- pdf_char_t ciphered[] = {
- 0xa6, 0x14, 0x2e, 0x8a,
- 0x51, 0x84, 0x84, 0x2a,
- 0xf0, 0x4d, 0xc8, 0x37,
- 0x23, 0x8b, 0xc6, 0xf0,
- 0x3a, 0x30, 0x0f, 0xcc,
- 0xb1, 0x04, 0x05, 0x47,
- 0x99, 0xf4, 0x0e, 0xed,
- 0x6f, 0xdf, 0xc5, 0x20
- };
-
- pdf_char_t key[] =
- {
- 0x29, 0xfd, 0x08, 0x08,
- 0x05, 0x00, 0x00, 0x00,
- 0x18, 0x92, 0xe7, 0xbf,
- 0xab, 0x17, 0x08, 0x08
- };
-
+
+ pdf_char_t out[32];
+
+ pdf_char_t key[16] =
+ {
+ 0x06, 0xa9, 0x21, 0x40,
+ 0x36, 0xb8, 0xa1, 0x5b,
+ 0x51, 0x2e, 0x03, 0xd5,
+ 0x34, 0x12, 0x00, 0x06
+ };
+
+ pdf_char_t plain[] =
+ {
+ 0x3d, 0xaf, 0xba, 0x42, /* iv vector */
+ 0x9d, 0x9e, 0xb4, 0x30,
+ 0xb4, 0x22, 0xda, 0x80,
+ 0x2c, 0x9f, 0xac, 0x41,
+
+ 'S', 'i', 'n', 'g', /* plain text */
+ 'l', 'e', ' ', 'b',
+ 'l', 'o', 'c', 'k',
+ ' ', 'm', 's', 'g',
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0x3d, 0xaf, 0xba, 0x42, /* iv vector */
+ 0x9d, 0x9e, 0xb4, 0x30,
+ 0xb4, 0x22, 0xda, 0x80,
+ 0x2c, 0x9f, 0xac, 0x41,
+
+ 0xe3, 0x53, 0x77, 0x9c, /* ciphered */
+ 0x10, 0x79, 0xae, 0xb8,
+ 0x27, 0x08, 0x94, 0x2d,
+ 0xbe, 0x77, 0x18, 0x1a
+ };
+
pdf_crypt_init();
pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
- plain_size = pdf_crypt_cipher_decrypt_size (cipher, ciphered, sizeof(ciphered));
- plain = pdf_alloc (plain_size);
-
- fail_if (pdf_crypt_cipher_decrypt (cipher,
- plain, plain_size,
- ciphered, sizeof(ciphered),
- &plain_size) != PDF_OK);
- fail_if (plain_size != 0);
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out, sizeof(out), ciphered, sizeof(ciphered), NULL) != PDF_OK);
+ fail_if (memcmp (out, plain, sizeof(out)) != 0);
- pdf_dealloc (plain);
pdf_crypt_cipher_destroy (cipher);
}
END_TEST
+
/*
* Test: pdf_crypt_cipher_decrypt_002
* Description:
@@ -96,7 +106,7 @@
START_TEST (pdf_crypt_cipher_decrypt_002)
{
pdf_crypt_cipher_t cipher;
- pdf_char_t *plain;
+ pdf_char_t plain[16];
pdf_size_t plain_size;
pdf_char_t * ciphered;
@@ -109,16 +119,148 @@
pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
pdf_crypt_cipher_setkey (cipher, NULL, 0);
- plain_size = pdf_crypt_cipher_decrypt_size (cipher, ciphered, ciphered_size);
- plain = pdf_alloc (plain_size);
-
fail_if (pdf_crypt_cipher_decrypt (cipher,
- plain, plain_size,
+ plain, sizeof(plain),
ciphered, ciphered_size,
&plain_size) != PDF_OK);
fail_if (plain_size != 0);
-
- pdf_dealloc (plain);
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
+
+
+
+/*
+ * Test: pdf_crypt_cipher_decrypt_003
+ * Description:
+ * Decrypt an ciphered buffer (AEV2).
+ * Success condition:
+ * The ouput data should be correct.
+ */
+
+START_TEST (pdf_crypt_cipher_decrypt_003)
+{
+ pdf_crypt_cipher_t cipher;
+
+ pdf_char_t out[80];
+
+ pdf_char_t key[16] =
+ {
+ 0x56, 0xe4, 0x7a, 0x38,
+ 0xc5, 0x59, 0x89, 0x74,
+ 0xbc, 0x46, 0x90, 0x3d,
+ 0xba, 0x29, 0x03, 0x49
+ };
+
+ pdf_char_t plain[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e,
+ 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa,
+ 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6,
+ 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e,
+ 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf,
+ 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad,
+ 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d,
+ 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55,
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
+ pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
+
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out, sizeof(out), ciphered, sizeof(ciphered), NULL) != PDF_OK);
+ fail_if (memcmp (out, plain, sizeof(out)) != 0);
+
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_crypt_cipher_decrypt_004
+ * Description:
+ * Decrypt an ciphered buffer incrementally (AEV2).
+ * Success condition:
+ * The ouput data should be correct.
+ */
+
+START_TEST (pdf_crypt_cipher_decrypt_004)
+{
+ pdf_crypt_cipher_t cipher;
+
+ pdf_char_t out[80];
+
+ pdf_char_t key[16] =
+ {
+ 0x56, 0xe4, 0x7a, 0x38,
+ 0xc5, 0x59, 0x89, 0x74,
+ 0xbc, 0x46, 0x90, 0x3d,
+ 0xba, 0x29, 0x03, 0x49
+ };
+
+ pdf_char_t plain[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e,
+ 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa,
+ 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6,
+ 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e,
+ 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf,
+ 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad,
+ 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d,
+ 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55,
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
+ pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out + 00, 16, ciphered + 00, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out + 16, 16, ciphered + 16, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out + 32, 16, ciphered + 32, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out + 48, 16, ciphered + 48, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_decrypt (cipher, out + 64, 16, ciphered + 64, 16, NULL) != PDF_OK);
+
+ fail_if (memcmp (out, plain, sizeof(out)) != 0);
+
pdf_crypt_cipher_destroy (cipher);
}
END_TEST
@@ -135,6 +277,8 @@
TCase *tc = tcase_create("pdf_crypt_cipher_decrypt");
tcase_add_test(tc, pdf_crypt_cipher_decrypt_001);
tcase_add_test(tc, pdf_crypt_cipher_decrypt_002);
+ tcase_add_test(tc, pdf_crypt_cipher_decrypt_003);
+ tcase_add_test(tc, pdf_crypt_cipher_decrypt_004);
return tc;
}
=== removed file 'torture/unit/base/crypt/pdf-crypt-cipher-encrypt-size.c'
--- torture/unit/base/crypt/pdf-crypt-cipher-encrypt-size.c 2008-10-03 16:08:19 +0000
+++ torture/unit/base/crypt/pdf-crypt-cipher-encrypt-size.c 1970-01-01 00:00:00 +0000
@@ -1,125 +0,0 @@
-/* -*- mode: C -*- Time-stamp: "2008-09-09 04:07:52 david"
- *
- * File: pdf-crypt-cipher-encrypt-size.c
- * Date: Wed Mar 12 12:43:00 2008
- *
- * GNU PDF Library - Unit tests for pdf_crypt_cipher_encrypt_size
- *
- */
-
-/* Copyright (C) 2008 Free Software Foundation, Inc. */
-
-/* This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-#include
-
-#include
-#include
-#include
-#include
-
-
-/*
- * Test: pdf_crypt_cipher_encrypt_size_001
- * Description:
- * Get the ciphered buffer size for an empty input buffer (AESV2).
- * Success condition:
- * Returns 32
- */
-START_TEST (pdf_crypt_cipher_encrypt_size_001)
-{
- pdf_crypt_cipher_t cipher;
- pdf_crypt_init();
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
- fail_if (pdf_crypt_cipher_encrypt_size (cipher, NULL, 0) != 32);
- pdf_crypt_cipher_destroy (cipher);
-}
-END_TEST
-
-
-/*
- * Test: pdf_crypt_cipher_encrypt_size_002
- * Description:
- * Get the ciphered buffer size for a 15 bytes buffer (AESV2).
- * Success condition:
- * Returns 32
- */
-START_TEST (pdf_crypt_cipher_encrypt_size_002)
-{
- pdf_crypt_cipher_t cipher;
- pdf_crypt_init();
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
- fail_if (pdf_crypt_cipher_encrypt_size (cipher, NULL, 15) != 32);
- pdf_crypt_cipher_destroy (cipher);
-
-}
-END_TEST
-
-
-/*
- * Test: pdf_crypt_cipher_encrypt_size_003
- * Description:
- * Get the ciphered buffer size for a empty buffer (V2).
- * Success condition:
- * Returns 0
- */
-START_TEST (pdf_crypt_cipher_encrypt_size_003)
-{
- pdf_crypt_cipher_t cipher;
- pdf_crypt_init();
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
- fail_if (pdf_crypt_cipher_encrypt_size (cipher, NULL, 0) != 0);
- pdf_crypt_cipher_destroy (cipher);
-}
-END_TEST
-
-
-
-/*
- * Test: pdf_crypt_cipher_encrypt_size_004
- * Description:
- * Get the ciphered buffer size for a 15 bytes buffer (V2).
- * Success condition:
- * Returns 15
- */
-START_TEST (pdf_crypt_cipher_encrypt_size_004)
-{
- pdf_crypt_cipher_t cipher;
- pdf_crypt_init();
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
- fail_if (pdf_crypt_cipher_encrypt_size (cipher, NULL, 15) != 15);
- pdf_crypt_cipher_destroy (cipher);
-}
-END_TEST
-
-
-
-
-/*
- * Test case creation function
- */
-TCase *
-test_pdf_crypt_cipher_encrypt_size (void)
-{
- TCase *tc = tcase_create("pdf_crypt_cipher_encrypt_size");
- tcase_add_test(tc, pdf_crypt_cipher_encrypt_size_001);
- tcase_add_test(tc, pdf_crypt_cipher_encrypt_size_002);
- tcase_add_test(tc, pdf_crypt_cipher_encrypt_size_003);
- tcase_add_test(tc, pdf_crypt_cipher_encrypt_size_004);
- return tc;
-}
-
-
-/* End of pdf-crypt-cipher-encrypt-size.c */
=== modified file 'torture/unit/base/crypt/pdf-crypt-cipher-encrypt.c'
--- torture/unit/base/crypt/pdf-crypt-cipher-encrypt.c 2008-11-29 16:21:37 +0000
+++ torture/unit/base/crypt/pdf-crypt-cipher-encrypt.c 2008-12-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 16:04:01 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 19:02:55 davazp"
*
* File: pdf-crypt-cipher-encrypt.c
* Date: Wed Mar 12 12:43:00 2008
@@ -34,70 +34,175 @@
/*
* Test: pdf_crypt_cipher_encrypt_001
* Description:
- * Encrypt a empty buffer (AESV2).
+ * Encrypt a buffer (V2).
* Success condition:
- * Returns PDF_OK
+ * Encrypted data should be correct.
*/
START_TEST (pdf_crypt_cipher_encrypt_001)
{
pdf_crypt_cipher_t cipher;
- pdf_char_t *out;
- pdf_char_t *in;
+ pdf_char_t out[14];
pdf_size_t out_size;
+ pdf_char_t in[14] = "Attack at dawn"; /* not trailing '\0' */
pdf_size_t in_size;
- pdf_char_t key[16]; /* unintialized data */
+ pdf_char_t key[6] = "Secret"; /* not trailing '\0' */
+
+ pdf_char_t ciphered[] =
+ {
+ 0x45, 0xA0, 0x1F, 0x64, 0x5F, 0xC3, 0x5B,
+ 0x38, 0x35, 0x52, 0x54, 0x4B, 0x9B, 0xF5
+ };
- in_size = 0;
-
pdf_crypt_init();
+
+ in_size = sizeof(in);
+ out_size = in_size;
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
- pdf_crypt_cipher_setkey (cipher, key, in_size);
- out_size = pdf_crypt_cipher_encrypt_size (cipher, in, in_size);
-
- out = pdf_alloc (out_size);
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
+ pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
fail_if (pdf_crypt_cipher_encrypt (cipher, out, out_size, in, in_size, &out_size) != PDF_OK);
+ fail_if (memcmp (out, ciphered, out_size) != 0);
- pdf_dealloc (out);
pdf_crypt_cipher_destroy (cipher);
}
END_TEST
-
/*
* Test: pdf_crypt_cipher_encrypt_002
* Description:
- * Encrypt a empty buffer (V2).
+ * Encrypt an ciphered buffer (AEV2).
* Success condition:
- * Returns PDF_OK
+ * The ouput data should be correct.
*/
+
START_TEST (pdf_crypt_cipher_encrypt_002)
{
pdf_crypt_cipher_t cipher;
- pdf_char_t *out;
- pdf_char_t *in;
- pdf_size_t out_size;
- pdf_size_t in_size;
- pdf_char_t key[16]; /* uninitialized data */
-
- in_size = 0;
-
- pdf_crypt_init();
-
- pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
- pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
- out_size = pdf_crypt_cipher_encrypt_size (cipher, in, in_size);
-
- out = pdf_alloc (out_size);
-
- fail_if (pdf_crypt_cipher_encrypt (cipher, out, out_size, in, in_size, &out_size) != PDF_OK);
-
- pdf_dealloc (out);
- pdf_crypt_cipher_destroy (cipher);
-}
-END_TEST
+
+ pdf_char_t out[80];
+
+ pdf_char_t key[16] =
+ {
+ 0x56, 0xe4, 0x7a, 0x38,
+ 0xc5, 0x59, 0x89, 0x74,
+ 0xbc, 0x46, 0x90, 0x3d,
+ 0xba, 0x29, 0x03, 0x49
+ };
+
+ pdf_char_t plain[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e,
+ 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa,
+ 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6,
+ 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e,
+ 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf,
+ 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad,
+ 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d,
+ 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55,
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
+ pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
+
+ fail_if (pdf_crypt_cipher_encrypt (cipher, out, sizeof(out), plain, sizeof(plain), NULL) != PDF_OK);
+ fail_if (memcmp (out, ciphered, sizeof(out)) != 0);
+
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_crypt_cipher_encrypt_003
+ * Description:
+ * Encrypt an ciphered buffer incrementally (AEV2).
+ * Success condition:
+ * The ouput data should be correct.
+ */
+
+START_TEST (pdf_crypt_cipher_encrypt_003)
+{
+ pdf_crypt_cipher_t cipher;
+
+ pdf_char_t out[80];
+
+ pdf_char_t key[16] =
+ {
+ 0x56, 0xe4, 0x7a, 0x38,
+ 0xc5, 0x59, 0x89, 0x74,
+ 0xbc, 0x46, 0x90, 0x3d,
+ 0xba, 0x29, 0x03, 0x49
+ };
+
+ pdf_char_t plain[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e,
+ 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa,
+ 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6,
+ 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e,
+ 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf,
+ 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad,
+ 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d,
+ 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55,
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
+ pdf_crypt_cipher_setkey (cipher, key, sizeof(key));
+ fail_if (pdf_crypt_cipher_encrypt (cipher, out + 00, 16, plain + 00, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_encrypt (cipher, out + 16, 16, plain + 16, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_encrypt (cipher, out + 32, 16, plain + 32, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_encrypt (cipher, out + 48, 16, plain + 48, 16, NULL) != PDF_OK);
+ fail_if (pdf_crypt_cipher_encrypt (cipher, out + 64, 16, plain + 64, 16, NULL) != PDF_OK);
+
+ fail_if (memcmp (out, ciphered, sizeof(out)) != 0);
+
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
@@ -111,6 +216,7 @@
TCase *tc = tcase_create("pdf_crypt_cipher_encrypt");
tcase_add_test(tc, pdf_crypt_cipher_encrypt_001);
tcase_add_test(tc, pdf_crypt_cipher_encrypt_002);
+ tcase_add_test(tc, pdf_crypt_cipher_encrypt_003);
return tc;
}
=== added file 'torture/unit/base/crypt/pdf-crypt-cipher-setkey.c'
--- torture/unit/base/crypt/pdf-crypt-cipher-setkey.c 1970-01-01 00:00:00 +0000
+++ torture/unit/base/crypt/pdf-crypt-cipher-setkey.c 2008-12-23 18:16:49 +0000
@@ -0,0 +1,111 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-23 19:15:33 davazp"
+ *
+ * File: pdf-crypt-cipher-decrypt.c
+ * Date: Tue Dec 23 17:36:21 2008
+ *
+ * GNU PDF Library - Unit tests for pdf_crypt_cipher_setkey
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+
+
+/*
+ * Test: pdf_crypt_cipher_setkey_001
+ * Description:
+ * Set a key of 16 bytes. (AESv2)
+ * Success condition:
+ * Returns PDF_OK
+ */
+START_TEST (pdf_crypt_cipher_setkey_001)
+{
+ pdf_crypt_cipher_t cipher;
+ pdf_crypt_init();
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
+
+ fail_if (pdf_crypt_cipher_setkey (cipher, "0123456789abcdef", 16) != PDF_OK);
+
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
+
+/*
+ * Test: pdf_crypt_cipher_setkey_002
+ * Description:
+ * Set a key of 3 bytes (AESv2)
+ * Success condition:
+ * Returns PDF_OK
+ */
+START_TEST (pdf_crypt_cipher_setkey_002)
+{
+ pdf_crypt_cipher_t cipher;
+ pdf_crypt_init();
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_AESV2, &cipher);
+
+ fail_if (pdf_crypt_cipher_setkey (cipher, "GNU", 3) == PDF_OK);
+
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
+
+/*
+ * Test: pdf_crypt_cipher_setkey_003
+ * Description:
+ * Set a key of 6 bytes (V2)
+ * Success condition:
+ * Returns PDF_OK
+ */
+START_TEST (pdf_crypt_cipher_setkey_003)
+{
+ pdf_crypt_cipher_t cipher;
+ pdf_crypt_init();
+ pdf_crypt_cipher_new (PDF_CRYPT_CIPHER_ALGO_V2, &cipher);
+
+ fail_if (pdf_crypt_cipher_setkey (cipher, "GNUGNU", 6) != PDF_OK);
+
+ pdf_crypt_cipher_destroy (cipher);
+}
+END_TEST
+
+
+
+
+/*
+ * Test case creation function
+ */
+TCase *
+test_pdf_crypt_cipher_setkey (void)
+{
+ TCase *tc = tcase_create("pdf_crypt_cipher_setkey");
+ tcase_add_test(tc, pdf_crypt_cipher_setkey_001);
+ tcase_add_test(tc, pdf_crypt_cipher_setkey_002);
+ tcase_add_test(tc, pdf_crypt_cipher_setkey_003);
+ return tc;
+}
+
+
+/* End of pdf-crypt-cipher-setkey.c */
+
=== modified file 'torture/unit/base/crypt/pdf-crypt-md-destroy.c'
--- torture/unit/base/crypt/pdf-crypt-md-destroy.c 2008-10-03 16:08:19 +0000
+++ torture/unit/base/crypt/pdf-crypt-md-destroy.c 2008-12-21 17:39:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-09-09 04:18:49 david"
+/* -*- mode: C -*- Time-stamp: "2008-12-15 18:17:41 davazp"
*
* File: pdf-crypt-md-destroy.c
* Date: Wed Mar 12 12:43:00 2008
@@ -42,7 +42,7 @@
{
pdf_crypt_md_t md;
pdf_crypt_init();
- pdf_crypt_md_new (&md, PDF_CRYPT_MD_MD5);
+ pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md);
fail_if (pdf_crypt_md_destroy (md));
}
END_TEST
=== modified file 'torture/unit/base/crypt/pdf-crypt-md-new.c'
--- torture/unit/base/crypt/pdf-crypt-md-new.c 2008-10-03 16:08:19 +0000
+++ torture/unit/base/crypt/pdf-crypt-md-new.c 2008-12-21 17:39:51 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-09-09 03:13:18 david"
+/* -*- mode: C -*- Time-stamp: "2008-12-15 18:14:03 davazp"
*
* File: pdf-crypt-md-new.c
* Date: Wed Mar 12 12:43:00 2008
@@ -42,7 +42,7 @@
{
pdf_crypt_md_t md;
pdf_crypt_init();
- fail_if ( pdf_crypt_md_new (&md, PDF_CRYPT_MD_MD5) != PDF_OK);
+ fail_if ( pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md) != PDF_OK);
pdf_crypt_md_destroy (md);
}
END_TEST
=== added file 'torture/unit/base/crypt/pdf-crypt-md-read.c'
--- torture/unit/base/crypt/pdf-crypt-md-read.c 1970-01-01 00:00:00 +0000
+++ torture/unit/base/crypt/pdf-crypt-md-read.c 2008-12-23 18:16:49 +0000
@@ -0,0 +1,152 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-23 17:42:38 davazp"
+ *
+ * File: pdf-crypt-md-read.c
+ * Date: Tue Dec 23 17:30:19 2008
+ *
+ * GNU PDF Library - Unit tests for pdf_crypt_md_read
+ *
+ */
+
+/* Copyright (C) 2008 Free Software Foundation, Inc. */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/*
+ * Test: pdf_crypt_md_read_001
+ * Description:
+ * Compute the md5 of an empty buffer.
+ * Success condition:
+ * Returns PDF_OK and output buffer matches.
+ */
+START_TEST (pdf_crypt_md_read_001)
+{
+ pdf_char_t *in;
+ pdf_char_t out[16];
+ pdf_crypt_md_t md;
+ pdf_char_t real_out[] = {
+ 0xd4, 0x1d, 0x8c, 0xd9,
+ 0x8f, 0x00, 0xb2, 0x04,
+ 0xe9, 0x80, 0x09, 0x98,
+ 0xec, 0xf8, 0x42, 0x7e
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md);
+
+ pdf_crypt_md_write (md, in, 0);
+
+ fail_if (pdf_crypt_md_read (md, out, sizeof(out)) != PDF_OK);
+ fail_if (memcmp (real_out, out, sizeof(out)));
+
+ pdf_crypt_md_destroy (md);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_crypt_md_read_002
+ * Description:
+ * Compute the md5 checksum of a string
+ * Success condition:
+ * The output data should be correct.
+ */
+START_TEST (pdf_crypt_md_read_002)
+{
+ pdf_char_t in[1] = "a";
+ pdf_char_t out[16];
+ pdf_crypt_md_t md;
+ pdf_char_t real_out[] = {
+ 0x0C, 0xC1, 0x75, 0xB9,
+ 0xC0, 0xF1, 0xB6, 0xA8,
+ 0x31, 0xC3, 0x99, 0xE2,
+ 0x69, 0x77, 0x26, 0x61
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md);
+
+ pdf_crypt_md_write (md, in, sizeof(in));
+
+ fail_if (pdf_crypt_md_read (md, out, sizeof(out)) != PDF_OK);
+ fail_if (memcmp (real_out, out, sizeof(out)));
+
+ pdf_crypt_md_destroy (md);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_crypt_md_read_003
+ * Description:
+ * Compute the md5 checksum of a string
+ * Success condition:
+ * The output data should be correct.
+ */
+START_TEST (pdf_crypt_md_read_003)
+{
+ pdf_char_t in[26] = "abcdefghijklmnopqrstuvwxyz";
+ pdf_char_t out[16];
+ pdf_crypt_md_t md;
+ pdf_char_t real_out[] = {
+ 0xC3, 0xFC, 0xD3, 0xD7,
+ 0x61, 0x92, 0xE4, 0x00,
+ 0x7D, 0xFB, 0x49, 0x6C,
+ 0xCA, 0x67, 0xE1, 0x3B
+ };
+
+ pdf_crypt_init();
+
+ pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md);
+
+ pdf_crypt_md_write (md, in, sizeof(in));
+
+ fail_if (pdf_crypt_md_read (md, out, sizeof(out)) != PDF_OK);
+ fail_if (memcmp (real_out, out, sizeof(out)));
+
+ pdf_crypt_md_destroy (md);
+}
+END_TEST
+
+
+
+
+/*
+ * Test case creation function
+ */
+TCase *
+test_pdf_crypt_md_read (void)
+{
+ TCase *tc = tcase_create("pdf_crypt_md_read");
+ tcase_add_test(tc, pdf_crypt_md_read_001);
+ tcase_add_test(tc, pdf_crypt_md_read_002);
+ tcase_add_test(tc, pdf_crypt_md_read_003);
+ return tc;
+}
+
+
+/* End of pdf-crypt-md-read.c */
+
=== renamed file 'torture/unit/base/crypt/pdf-crypt-md-hash.c' => 'torture/unit/base/crypt/pdf-crypt-md-write.c'
--- torture/unit/base/crypt/pdf-crypt-md-hash.c 2008-10-03 16:08:19 +0000
+++ torture/unit/base/crypt/pdf-crypt-md-write.c 2008-12-23 18:08:31 +0000
@@ -1,9 +1,9 @@
-/* -*- mode: C -*- Time-stamp: "2008-09-09 04:18:07 david"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 17:47:49 davazp"
*
* File: pdf-crypt-md-hash.c
* Date: Wed Mar 12 12:43:00 2008
*
- * GNU PDF Library - Unit tests for pdf_crypt_md_hash
+ * GNU PDF Library - Unit tests for pdf_crypt_md_write
*
*/
@@ -32,48 +32,36 @@
/*
- * Test: pdf_crypt_md_hash_001
+ * Test: pdf_crypt_md_write_001
* Description:
- * Compute the md5 of an empty buffer.
+ * Pass an empty message
* Success condition:
- * Returns PDF_OK and output buffer matches.
+ * Returns PDF_OK.
*/
-START_TEST (pdf_crypt_md_hash_001)
+START_TEST (pdf_crypt_md_write_001)
{
- pdf_char_t *in;
- pdf_char_t out[16];
+ pdf_char_t * in;
pdf_crypt_md_t md;
- pdf_char_t real_out[] = {
- 0xd4, 0x1d, 0x8c, 0xd9,
- 0x8f, 0x00, 0xb2, 0x04,
- 0xe9, 0x80, 0x09, 0x98,
- 0xec, 0xf8, 0x42, 0x7e
- };
-
pdf_crypt_init();
-
- pdf_crypt_md_new (&md, PDF_CRYPT_MD_MD5);
- fail_if (pdf_crypt_md_hash (md, out, sizeof(out), in, 0) != PDF_OK);
- fail_if (!memcmp (real_out, out, sizeof(out)));
-
+ pdf_crypt_md_new (PDF_CRYPT_MD_MD5, &md);
+ fail_if (pdf_crypt_md_write (md, in, 0) != PDF_OK);
pdf_crypt_md_destroy (md);
}
END_TEST
-
/*
* Test case creation function
*/
TCase *
-test_pdf_crypt_md_hash (void)
+test_pdf_crypt_md_write (void)
{
- TCase *tc = tcase_create("pdf_crypt_md_hash");
- tcase_add_test(tc, pdf_crypt_md_hash_001);
+ TCase *tc = tcase_create("pdf_crypt_md_write");
+ tcase_add_test(tc, pdf_crypt_md_write_001);
return tc;
}
-/* End of pdf-crypt-md-hash.c */
+/* End of pdf-crypt-md-write.c */
=== modified file 'torture/unit/base/crypt/tsuite-crypt.c'
--- torture/unit/base/crypt/tsuite-crypt.c 2008-09-10 12:32:07 +0000
+++ torture/unit/base/crypt/tsuite-crypt.c 2008-12-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/09/10 14:30:20 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 17:43:16 davazp"
*
* File: tsuite-alloc.c
* Author: Jose E. Marchesi (address@hidden)
@@ -28,6 +28,7 @@
extern TCase *test_pdf_crypt_init (void);
extern TCase *test_pdf_crypt_cipher_new (void);
+extern TCase *test_pdf_crypt_cipher_setkey (void);
extern TCase *test_pdf_crypt_cipher_destroy (void);
extern TCase *test_pdf_crypt_cipher_setkey (void);
extern TCase *test_pdf_crypt_cipher_encrypt_size (void);
@@ -35,7 +36,8 @@
extern TCase *test_pdf_crypt_cipher_encrypt (void);
extern TCase *test_pdf_crypt_cipher_decrypt (void);
extern TCase *test_pdf_crypt_md_new (void);
-extern TCase *test_pdf_crypt_md_hash (void);
+extern TCase *test_pdf_crypt_md_write (void);
+extern TCase *test_pdf_crypt_md_read (void);
extern TCase *test_pdf_crypt_md_destroy (void);
@@ -49,14 +51,14 @@
suite_add_tcase (s, test_pdf_crypt_init ());
suite_add_tcase (s, test_pdf_crypt_cipher_new ());
+ suite_add_tcase (s, test_pdf_crypt_cipher_setkey ());
suite_add_tcase (s, test_pdf_crypt_cipher_destroy ());
- suite_add_tcase (s, test_pdf_crypt_cipher_encrypt_size ());
- suite_add_tcase (s, test_pdf_crypt_cipher_decrypt_size ());
suite_add_tcase (s, test_pdf_crypt_cipher_encrypt ());
suite_add_tcase (s, test_pdf_crypt_cipher_decrypt ());
suite_add_tcase (s, test_pdf_crypt_md_new ());
- suite_add_tcase (s, test_pdf_crypt_md_hash ());
+ suite_add_tcase (s, test_pdf_crypt_md_write ());
+ suite_add_tcase (s, test_pdf_crypt_md_read ());
suite_add_tcase (s, test_pdf_crypt_md_destroy ());
return s;
=== modified file 'torture/unit/base/stm/pdf-stm-read.c'
--- torture/unit/base/stm/pdf-stm-read.c 2008-10-05 15:08:05 +0000
+++ torture/unit/base/stm/pdf-stm-read.c 2008-12-25 15:49:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-10-05 13:07:53 gerel"
+/* -*- mode: C -*- Time-stamp: "2008-12-25 16:21:49 davazp"
*
* File: pdf-stm-read.c
* Date: Sat Sep 20 15:20:17 2008
@@ -615,6 +615,120 @@
END_TEST
+
+/*
+ * Test: pdf_stm_read_011
+ * Description:
+ * Create a memory-based writing stream and attach an V2 cipher filter
+ * decode to it.
+ * Success condition:
+ * The decoded data should be correct.
+ */
+START_TEST (pdf_stm_read_011)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+
+ pdf_char_t out[14];
+ pdf_size_t out_size = sizeof(out);
+ pdf_char_t in[] =
+ {
+ 0x45, 0xA0, 0x1F, 0x64, 0x5F, 0xC3, 0x5B,
+ 0x38, 0x35, 0x52, 0x54, 0x4B, 0x9B, 0xF5
+ };
+ pdf_size_t in_size = sizeof(in);
+ pdf_char_t key[6] = "Secret"; /* not trailing '\0' */
+ pdf_size_t keysize = sizeof(key);
+ pdf_char_t plaintext[] = "Attack at dawn";
+ pdf_char_t read;
+
+ pdf_crypt_init();
+
+ fail_if ( pdf_stm_mem_new (in, in_size, 0, PDF_STM_READ, &stm) != PDF_OK);
+
+ pdf_hash_new (NULL, ¶ms);
+ pdf_hash_add (params, "Key", key, NULL);
+ pdf_hash_add (params, "KeySize", &keysize, NULL);
+
+ fail_if ( pdf_stm_install_filter (stm, PDF_STM_FILTER_V2_DEC, params) != PDF_OK);
+
+ read = pdf_stm_read (stm, out, out_size);
+ fail_if (read != out_size);
+
+ fail_if (memcmp (out, plaintext, read) != 0);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_stm_read_012
+ * Description:
+ * Create a memory-based reading stream and attach an AESV2 filter
+ * decoder to it.
+ * Success condition:
+ * The decoded data should be correct.
+ */
+START_TEST (pdf_stm_read_012)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+ pdf_char_t out[48];
+ pdf_size_t out_size;
+
+ pdf_char_t key[] =
+ {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+ };
+ pdf_size_t keysize = sizeof(key);
+
+ pdf_char_t plain[] =
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* iv */
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* content */
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x0f,
+ /* padding */
+ /* 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f */
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* iv vector */
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xbb, 0x03, 0x13, 0xee, 0x2f, 0x65, 0x43, 0xa9, /* content */
+ 0x04, 0xf2, 0x8e, 0xff, 0x68, 0x59, 0x05, 0x35,
+ 0x81, 0x7e, 0x24, 0x33, 0x5f, 0x18, 0x72, 0x12, /* padding */
+ 0x8c, 0xb8, 0x4c, 0x23, 0x59, 0xd0, 0xe0, 0x36,
+ };
+
+ pdf_crypt_init();
+
+ pdf_hash_new (NULL, ¶ms);
+ pdf_hash_add (params, "Key", key, NULL);
+ pdf_hash_add (params, "KeySize", &keysize, NULL);
+
+ fail_if ( pdf_stm_mem_new (ciphered, sizeof(ciphered), 0, PDF_STM_READ, &stm) != PDF_OK);
+ fail_if ( pdf_stm_install_filter (stm, PDF_STM_FILTER_AESV2_DEC, params) != PDF_OK);
+
+ out_size = pdf_stm_read (stm, out , sizeof(out));
+
+ fail_if (out_size != sizeof(plain));
+ fail_if (memcmp (out, plain, out_size) != 0);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
/*
* Test case creation function
*/
@@ -632,6 +746,8 @@
tcase_add_test(tc, pdf_stm_read_007);
tcase_add_test(tc, pdf_stm_read_008);
tcase_add_test(tc, pdf_stm_read_009);
+ tcase_add_test(tc, pdf_stm_read_011);
+ tcase_add_test(tc, pdf_stm_read_012);
return tc;
}
=== modified file 'torture/unit/base/stm/pdf-stm-write.c'
--- torture/unit/base/stm/pdf-stm-write.c 2008-10-05 15:08:05 +0000
+++ torture/unit/base/stm/pdf-stm-write.c 2008-12-25 15:49:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-10-05 13:06:54 gerel"
+/* -*- mode: C -*- Time-stamp: "2008-12-25 16:48:54 davazp"
*
* File: pdf-stm-write.c
* Date: Sun Sep 21 16:37:27 2008
@@ -427,6 +427,273 @@
END_TEST
+
+
+
+/*
+ * Test: pdf_stm_write_008
+ * Description:
+ * Create a memory-based writing stream and attach an V2 filter without parameters.
+ * Success condition:
+ * The installation of the filter should fail.
+ */
+START_TEST (pdf_stm_write_008)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+ pdf_char_t buffer[16];
+ pdf_status_t ret;
+
+ pdf_crypt_init();
+
+ ret = pdf_stm_mem_new (buffer, sizeof(buffer), 0, PDF_STM_WRITE, &stm);
+ fail_if (ret != PDF_OK);
+
+ pdf_hash_new (NULL, ¶ms);
+
+ ret = pdf_stm_install_filter (stm, PDF_STM_FILTER_V2_ENC, params);
+ fail_if (ret == PDF_OK);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_stm_write_009
+ * Description:
+ * Create a memory-based writing stream and attach an V2 filter
+ * encoder to it.
+ * Success condition:
+ * The encoded data should be correct.
+ */
+START_TEST (pdf_stm_write_009)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+
+ pdf_char_t out[14];
+ pdf_size_t out_size = sizeof(out);
+ pdf_char_t in[14] = "Attack at dawn"; /* not trailing '\0' */
+ pdf_size_t in_size = sizeof(in);
+ pdf_char_t key[6] = "Secret"; /* not trailing '\0' */
+ pdf_size_t keysize = sizeof(key);
+
+ pdf_char_t ciphered[] = {
+ 0x45, 0xA0, 0x1F, 0x64, 0x5F, 0xC3, 0x5B,
+ 0x38, 0x35, 0x52, 0x54, 0x4B, 0x9B, 0xF5
+ };
+
+ pdf_char_t written;
+
+ pdf_crypt_init();
+
+ fail_if ( pdf_stm_mem_new (out, out_size, 0, PDF_STM_WRITE, &stm) != PDF_OK);
+
+ pdf_hash_new (NULL, ¶ms);
+ pdf_hash_add (params, "Key", key, NULL);
+ pdf_hash_add (params, "KeySize", &keysize, NULL);
+
+ fail_if ( pdf_stm_install_filter (stm, PDF_STM_FILTER_V2_ENC, params) != PDF_OK);
+
+ written = pdf_stm_write (stm, in, in_size);
+ fail_if (written != out_size);
+
+ pdf_stm_flush (stm, PDF_TRUE);
+
+ fail_if (memcmp (out, ciphered, written) != 0);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_stm_write_010
+ * Description:
+ * Create a memory-based writing stream and attach an AESV2 filter
+ * encoder to it.
+ * Success condition:
+ * The encoded data should be correct.
+ */
+START_TEST (pdf_stm_write_010)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+ pdf_char_t out[96];
+ pdf_char_t key[16] =
+ {
+ 0x56, 0xe4, 0x7a, 0x38,
+ 0xc5, 0x59, 0x89, 0x74,
+ 0xbc, 0x46, 0x90, 0x3d,
+ 0xba, 0x29, 0x03, 0x49
+ };
+ pdf_size_t keysize = sizeof(key);
+ pdf_char_t plain[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c, /* iv vector */
+ 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9,
+
+ 0xc3, 0x0e, 0x32, 0xff, 0xed, 0xc0, 0x77, 0x4e,
+ 0x6a, 0xff, 0x6a, 0xf0, 0x86, 0x9f, 0x71, 0xaa,
+ 0x0f, 0x3a, 0xf0, 0x7a, 0x9a, 0x31, 0xa9, 0xc6,
+ 0x84, 0xdb, 0x20, 0x7e, 0xb0, 0xef, 0x8e, 0x4e,
+ 0x35, 0x90, 0x7a, 0xa6, 0x32, 0xc3, 0xff, 0xdf,
+ 0x86, 0x8b, 0xb7, 0xb2, 0x9d, 0x3d, 0x46, 0xad,
+ 0x83, 0xce, 0x9f, 0x9a, 0x10, 0x2e, 0xe9, 0x9d,
+ 0x49, 0xa5, 0x3e, 0x87, 0xf4, 0xc3, 0xda, 0x55,
+ };
+
+ pdf_crypt_init();
+
+ pdf_hash_new (NULL, ¶ms);
+ pdf_hash_add (params, "Key", key, NULL);
+ pdf_hash_add (params, "KeySize", &keysize, NULL);
+
+ fail_if ( pdf_stm_mem_new (out, sizeof(out), 0, PDF_STM_WRITE, &stm) != PDF_OK);
+ fail_if ( pdf_stm_install_filter (stm, PDF_STM_FILTER_AESV2_ENC, params) != PDF_OK);
+
+ pdf_stm_write (stm, plain + 00 , 16);
+ pdf_stm_write (stm, plain + 16 , 16);
+ pdf_stm_write (stm, plain + 32 , 16);
+ pdf_stm_write (stm, plain + 48 , 16);
+ pdf_stm_write (stm, plain + 64 , 16);
+
+ pdf_stm_flush (stm, PDF_TRUE);
+
+ fail_if (memcmp (out, ciphered, sizeof(ciphered)) != 0);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_stm_write_011
+ * Description:
+ * Create a memory-based writing stream and attach an MD5
+ * encoder to it.
+ * Success condition:
+ * The output data should be correct.
+ */
+START_TEST (pdf_stm_write_011)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+ pdf_char_t in[26] = "abcdefghijklmnopqrstuvwxyz";
+ pdf_char_t out[16];
+ pdf_crypt_md_t md;
+ pdf_char_t real_out[] = {
+ 0xC3, 0xFC, 0xD3, 0xD7,
+ 0x61, 0x92, 0xE4, 0x00,
+ 0x7D, 0xFB, 0x49, 0x6C,
+ 0xCA, 0x67, 0xE1, 0x3B
+ };
+
+ pdf_crypt_init();
+
+ pdf_hash_new (NULL, ¶ms);
+
+ fail_if ( pdf_stm_mem_new (out, sizeof(out), 0, PDF_STM_WRITE, &stm) != PDF_OK);
+ fail_if ( pdf_stm_install_filter (stm, PDF_STM_FILTER_MD5_ENC, params) != PDF_OK);
+
+ pdf_stm_write (stm, in, sizeof(in));
+ pdf_stm_flush (stm, PDF_TRUE);
+
+ fail_if (memcmp (out, real_out, sizeof(out)) != 0);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
+/*
+ * Test: pdf_stm_write_012
+ * Description:
+ * Create a memory-based writing stream and attach an AESV2 filter
+ * decoder to it.
+ * Success condition:
+ * The decoded data should be correct.
+ */
+START_TEST (pdf_stm_write_012)
+{
+ pdf_stm_t stm;
+ pdf_hash_t params;
+ pdf_char_t out[48];
+
+ pdf_char_t key[] =
+ {
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+ };
+ pdf_size_t keysize = sizeof(key);
+
+ pdf_char_t plain[] =
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* iv */
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* content */
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x0f,
+ /* padding */
+ /* 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f */
+ };
+
+ pdf_char_t ciphered[] =
+ {
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* iv vector */
+ 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+ 0xbb, 0x03, 0x13, 0xee, 0x2f, 0x65, 0x43, 0xa9, /* content */
+ 0x04, 0xf2, 0x8e, 0xff, 0x68, 0x59, 0x05, 0x35,
+ 0x81, 0x7e, 0x24, 0x33, 0x5f, 0x18, 0x72, 0x12, /* padding */
+ 0x8c, 0xb8, 0x4c, 0x23, 0x59, 0xd0, 0xe0, 0x36,
+ };
+
+ pdf_crypt_init();
+
+ pdf_hash_new (NULL, ¶ms);
+ pdf_hash_add (params, "Key", key, NULL);
+ pdf_hash_add (params, "KeySize", &keysize, NULL);
+
+ fail_if ( pdf_stm_mem_new (out, sizeof(out), 0, PDF_STM_WRITE, &stm) != PDF_OK);
+ fail_if ( pdf_stm_install_filter (stm, PDF_STM_FILTER_AESV2_ENC, params) != PDF_OK);
+
+ pdf_stm_write (stm, plain , sizeof(plain));
+ pdf_stm_flush (stm, PDF_TRUE);
+
+ fail_if (memcmp (out, ciphered, sizeof(out)) != 0);
+
+ pdf_hash_destroy (params);
+ pdf_stm_destroy (stm);
+}
+END_TEST
+
+
+
/*
* Test case creation function
*/
@@ -442,7 +709,12 @@
tcase_add_test(tc, pdf_stm_write_005);
tcase_add_test(tc, pdf_stm_write_006);
tcase_add_test(tc, pdf_stm_write_007);
-
+ tcase_add_test(tc, pdf_stm_write_008);
+ tcase_add_test(tc, pdf_stm_write_009);
+ tcase_add_test(tc, pdf_stm_write_010);
+ tcase_add_test(tc, pdf_stm_write_011);
+ tcase_add_test(tc, pdf_stm_write_012);
+
return tc;
}
# Begin bundle
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