pdf-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[pdf-devel] *****POSSIBLE SPAM***** Crypt module


From: David Vazquez
Subject: [pdf-devel] *****POSSIBLE SPAM***** Crypt module
Date: Tue, 23 Dec 2008 19:21:07 +0100

SPAM Ranking:   (4.4 points, 4.0 required)
Text in Spanish, Italian and English

SPANISH:
Spamassassin ha detectado este correo como posible spam. Aunque el sistema
descarta por comodidad los correos con valor mayor de 5, mantenemos un margen
de seguridad para evitar falsos positivos.

Si este correo es válido, para evitar que siga siendo detectado como spam,
reenvie este correo (manteniendo el adjunto original) a    address@hidden

Si este correo es realmente SPAM, puede mejorar la eficiencia del sistema
enviando este correo (manteniendo el adjunto original) a  address@hidden

ITALIAN:
Spamassassin ha catalogo questo email come Spam possibile. Anche se le poste
di scarto del sistema con lo Spam stimano la tomaia a 5, questo spacco di
sicurezza impedisce i positives falsi di goccia del sistema.

Se questa posta è utile, per impedire i positives falsi futuri con questo
genere di poste, prego di andata esso (con il collegamento originale) a
address@hidden
Se questa posta è Spam, potete contribuire ad aumentare l'esattezza della
spedizione del sistema questa posta (con il collegamento originale) a

ENGLISH:
Spamassassin has catalog this email as possible spam. Although the system
discard mails with spam value upper to 5, this security gap prevents system
drop false positives.

If this mail is useful, for prevent future false positives with this kind of
mails, please forward it (with the original attachment) to     address@hidden

If this mail is realy SPAM, you can help to increase the accuracy of the
system forwarding this mail (with the original attachment) to address@hidden

------------------------------------------------------------------------------

Content preview:  Sorry, I forgot to add a couple of files. I attach the patch
   again :-). # 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: f2f0b5362286af0d179186833e18743892c41664 # 
timestamp:
   2008-12-23 19:17:04 +0100 # base_revision_id: address@hidden
   # # Begin patch === modified file 'ChangeLog' --- ChangeLog 2008-12-10 
20:45:27
   +0000 +++ ChangeLog 2008-12-23 18:08:31 +0000 @@ -1,3 +1,64 @@ +2008-12-23
   David Vazquez <address@hidden> + + * 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 
<address@hidden>
   + + * 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 
<address@hidden>
   + + * 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 <address@hidden> + + * 
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 <address@hidden> + + * torture/unit/base/stm/pdf-stm-read.c:
   New test. + + * doc/gnupdf-tsd.texi [...] 

Content analysis details:   (4.4 points, 4.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 4.1 FH_HOST_EQ_DYNAMICIP   Host is dynamicip
 0.2 SARE_RMML_Stock1       BODY: SARE_RMML_Stock1
 0.0 BAYES_50               BODY: Bayesian spam probability is 40 to 60%
                            [score: 0.5000]
 0.1 RDNS_DYNAMIC           Delivered to trusted network by host with
                            dynamic-looking rDNS

The original message was not completely plain text, and may be unsafe to
open with some email clients; in particular, it may contain a virus,
or confirm that your address can receive spam.  If you wish to view
it, it may be safer to save it to a file and open it with an editor.

--- Begin Message --- Subject: Crypt module Date: Tue, 23 Dec 2008 19:21:07 +0100 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux)
Sorry, I forgot to add a couple of files. I attach the patch again :-).

# 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: f2f0b5362286af0d179186833e18743892c41664
# timestamp: 2008-12-23 19:17:04 +0100
# base_revision_id: address@hidden
# 
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog   2008-12-10 20:45:27 +0000
+++ ChangeLog   2008-12-23 18:08:31 +0000
@@ -1,3 +1,64 @@
+2008-12-23  David Vazquez  <address@hidden>
+
+       * 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  <address@hidden>
+
+       * 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  <address@hidden>
+
+       * 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  <address@hidden>
+
+       * 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  <address@hidden>
+
+       * 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  <address@hidden>
 
        * 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-23 18:08: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,41 @@
 @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 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 +6108,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 +6160,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 +6178,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 +6198,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 +6212,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 +6241,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 +6264,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-23 18:08:31 +0000
@@ -307,6 +307,8 @@
 *p = 666;
 @end example
 @end table
+
+
 @end deftypefun
 
 @deftypefun void pdf_dealloc (const void address@hidden)
@@ -8130,7 +8132,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 +8340,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 +8379,7 @@
 @end table
 @end deftypefun
 
+
 @node Creating and destroying Ciphers
 @subsection Creating and destroying Ciphers
 
@@ -8507,67 +8511,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 +8529,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 +8638,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 +8675,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 +8700,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 +8708,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 +8798,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-23 18:08:31 +0000
@@ -45,6 +45,9 @@
                      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-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 <pdf-error.h>
 #include <pdf-crypt-c-aesv2.h>
 
+
 #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 <pdf-alloc.h>
 #include <pdf-crypt-c-aesv2.h>
 #include <pdf-crypt-c-v2.h>
-
+#include <string.h>
 
 /* 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 <pdf-alloc.h>
 #include <pdf-stm-buffer.h>
+#include <stdlib.h>
 
 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-21 17:39:51 +0000
@@ -0,0 +1,277 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-21 14:17:04 davazp"
+ *
+ *       File:         pdf-stm-f-aesv2.c
+ *       Date:         Sun Dec 14 20:13:53 2008
+ *
+ *       GNU PDF Library - AESV2 stream filter
+ *
+ */
+
+/* Copyright (C) 2007, 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <pdf-stm-f-aesv2.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define AESV2_CACHE_SIZE 1024
+
+
+/* Internal state */
+struct pdf_stm_f_aesv2_s
+{
+  pdf_crypt_cipher_t cipher;
+  pdf_stm_buffer_t 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 the cache buffer */
+              filter_state->cache = pdf_stm_buffer_new (AESV2_CACHE_SIZE);
+              if (filter_state->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_stm_buffer_t cache = filter_state->cache;
+  pdf_size_t in_size;
+  
+  in_size = in->wp - in->rp;
+  
+  /* We need operate on whole buffer in a single function
+     call. So, we must to cache all input before. */
+  if (in_size != 0)
+    {
+      /* if CACHE is not too large, we must resize it in order to we
+         can append the IN buffer. */
+      if ((cache->size - cache->wp) < in_size)
+        {
+          if (pdf_stm_buffer_resize (cache, cache->size + in_size) != PDF_OK)
+            return PDF_ERROR;
+        }
+      
+      memcpy (cache->data + cache->wp, in->data, in_size);
+
+      cache->wp += in_size;
+      in->rp    += in_size;
+    }
+
+
+  if (finish_p == PDF_TRUE)
+    {
+      /* Once we have collected all input, then we can encrypt/decrypt. */
+      pdf_size_t cache_size;
+      pdf_size_t out_size;
+      pdf_size_t written;
+
+      cache_size  = cache->wp - cache->rp;
+      out_size = out->size - out->wp;
+
+      if (cache_size == 0)
+        return PDF_ENINPUT;
+
+
+      if (mode == PDF_STM_F_AESV2_MODE_ENCODE) /* encoding data */
+        {
+          pdf_size_t aux_size;
+          aux_size = pdf_crypt_cipher_encrypt_size (filter_state->cipher, 
cache->data, cache_size);
+
+          if (aux_size > out_size)
+            {
+              /* We should can return PDF_ENOUTPUT. However the
+                 output buffer is assumed to be full if we return
+                 PDF_ENOUTPUT, but we can not write it partially.  */
+              return PDF_ERROR;
+            }
+          else
+            {
+              pdf_crypt_cipher_encrypt (filter_state->cipher,
+                                        out->data,
+                                        out_size,
+                                        cache->data,
+                                        cache_size,
+                                        &written);
+            }
+        }
+      else if (mode == PDF_STM_F_AESV2_MODE_DECODE) /* decoding data */
+        {
+          pdf_size_t aux_size;
+          aux_size = pdf_crypt_cipher_decrypt_size (filter_state->cipher, 
cache->data, cache_size);
+
+          if (aux_size > out_size)
+            {
+              return PDF_ERROR;
+            }
+          else
+            {
+              pdf_crypt_cipher_decrypt (filter_state->cipher,
+                                        out->data,
+                                        out_size,
+                                        cache->data,
+                                        cache_size,
+                                        &written);
+            }
+        }
+
+      /* Update output buffer */
+      cache->rp += cache_size;
+      out->wp += written;
+    }
+
+  return PDF_ENINPUT;
+}
+
+
+
+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->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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PDF_STM_F_AESV2_H
+#define PDF_STM_F_AESV2_H
+
+#include <config.h>
+#include <pdf-types.h>
+#include <pdf-hash.h>
+#include <pdf-alloc.h>
+#include <pdf-stm-buffer.h>
+#include <pdf-crypt.h>
+#include <stdio.h>
+
+
+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-21 17:39:51 +0000
@@ -0,0 +1,169 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-21 14:10:04 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <pdf-stm-f-md5.h>
+#include <string.h>
+
+#define MD5_OUTPUT_SIZE 16
+#define MD5_CACHE_SIZE 1024
+
+
+/* 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;
+
+          /* Initialize the buffer cache */
+          filter_state->cache = pdf_stm_buffer_new (MD5_CACHE_SIZE);
+          if (filter_state->cache != NULL)
+            {
+              ret = PDF_OK;
+              *state = filter_state;
+            }
+          else
+            {
+              ret = PDF_ENOMEM;
+            }
+        }
+      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;
+  
+  in_size = in->wp - in->rp;
+  
+  /* We need operate on whole buffer in a single function
+     call. So, we must to cache all input before. */
+  if (in_size != 0)
+    {
+      if ((cache->size - cache->wp) < in_size)
+        {
+          if (pdf_stm_buffer_resize (cache, cache->size + in_size) != PDF_OK)
+            return PDF_ERROR;
+        }
+      
+      memcpy (cache->data + cache->wp, in->data, in_size);
+
+      cache->wp += in_size;
+      in->rp    += in_size;
+    }
+
+  if (finish_p == PDF_TRUE)
+    {
+      /* Once we have collected all input, then we can go on. */
+      pdf_size_t cache_size;
+      pdf_size_t out_size;
+
+      cache_size  = cache->wp - cache->rp;
+
+      if (cache_size == 0)
+        return PDF_ENINPUT;
+
+      out_size = out->size - out->wp;
+
+      if (MD5_OUTPUT_SIZE > out_size)
+        {
+          /* We should can return PDF_ENOUTPUT. However the
+             output buffer is assumed to be full if we return
+             PDF_ENOUTPUT, but we can not write it partially.  */
+          return PDF_ERROR;
+        }
+      else
+        {
+          pdf_crypt_md_hash (filter_state->md,
+                             out->data,
+                             out_size,
+                             cache->data,
+                             cache_size);
+        }
+
+      /* Update output buffer */
+      cache->rp += cache_size;
+      out->wp += MD5_OUTPUT_SIZE;
+    }
+
+
+  return PDF_ENINPUT;
+}
+
+
+
+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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PDF_STM_F_MD5_H
+#define PDF_STM_F_MD5_H
+
+#include <config.h>
+#include <pdf-types.h>
+#include <pdf-hash.h>
+#include <pdf-alloc.h>
+#include <pdf-stm-buffer.h>
+#include <pdf-crypt.h>
+#include <stdio.h>
+
+
+/* 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-21 17:39:51 +0000
@@ -0,0 +1,222 @@
+/* -*- mode: C -*- Time-stamp: "2008-12-20 16:45:27 davazp"
+ *
+ *       File:         pdf-stm-f-v2.c
+ *       Date:         Tue Jul 10 23:44:00 2007
+ *
+ *       GNU PDF Library - V2 stream filter
+ *
+ */
+
+/* Copyright (C) 2007, 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <pdf-stm-f-v2.h>
+
+
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PDF_STM_F_V2_H
+#define PDF_STM_F_V2_H
+
+#include <config.h>
+#include <pdf-types.h>
+#include <pdf-hash.h>
+#include <pdf-alloc.h>
+#include <pdf-stm-buffer.h>
+#include <pdf-crypt.h>
+#include <stdio.h>
+
+
+/* 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-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/12/08 20:02:37 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 16:21:42 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,44 @@
         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 +165,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-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "08/11/29 15:10:34 jemarch"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 16:20:10 davazp"
  *
  *       File:         pdf-stm-filter.h
  *       Date:         Thu Jun 12 22:05:06 2008
@@ -35,6 +35,9 @@
 #include <pdf-stm-f-null.h>
 #include <pdf-stm-f-ahex.h>
 #include <pdf-stm-f-rl.h>
+#include <pdf-stm-f-v2.h>
+#include <pdf-stm-f-aesv2.h>
+#include <pdf-stm-f-md5.h>
 
 #if defined(HAVE_LIBZ)
 #  include <pdf-stm-f-flate.h>
@@ -56,6 +59,13 @@
   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 <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <pdf.h>
-#include <check.h>
-
-
-/*
- * 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 <http://www.gnu.org/licenses/>.
+ * 
  */
 
 #include <config.h>
@@ -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 <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <pdf.h>
-#include <check.h>
-
-
-/*
- * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <pdf.h>
+#include <check.h>
+
+
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <pdf.h>
+#include <check.h>
+
+
+/*
+ * 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-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-10-05 13:07:53 gerel"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 17:33:54 davazp"
  *
  *       File:         pdf-stm-read.c
  *       Date:         Sat Sep 20 15:20:17 2008
@@ -615,6 +615,58 @@
 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, &params);
+ *   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 case creation function
  */
@@ -632,6 +684,7 @@
   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); */
 
   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-23 18:08:31 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2008-10-05 13:06:54 gerel"
+/* -*- mode: C -*- Time-stamp: "2008-12-23 17:33:28 davazp"
  *
  *       File:         pdf-stm-write.c
  *       Date:         Sun Sep 21 16:37:27 2008
@@ -427,6 +427,149 @@
 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, &params);
+ *   
+ *   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, &params);
+ *   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)
+ * {
+ * }
+ * END_TEST
+ * 
+ * 
+ * 
+ * /\*
+ *  * Test: pdf_stm_write_011
+ *  * Description:
+ *  *   Create a memory-based writing stream and attach an MD5 filter
+ *  *   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, &params);
+ * 
+ *   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 case creation function
  */
@@ -442,7 +585,13 @@
   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);
+   */
+
   return tc;
 }
 

# Begin bundle
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

--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]