pdf-devel
[Top][All Lists]
Advanced

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

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


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

SPAM Ranking:   (4.3 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:  Task #80 done. Crypt module works incrementally now. I have
   changed a few the API, added several tests, and updated the documentation.
   It also fixes the trouble with aesv2 testing. I have written a couple of
  test vectors both encrypt and decrypt from the RFC3602. [...] 

Content analysis details:   (4.3 points, 4.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 4.1 FH_HOST_EQ_DYNAMICIP   Host is dynamicip
 0.1 SARE_RMML_Stock9       BODY: SARE_RMML_Stock9
 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: [PATCH] Crypt module Date: Tue, 23 Dec 2008 19:15:18 +0100 User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux)
Task #80 done. Crypt module works incrementally now. I have changed a
few the API, added several tests, and updated the documentation.

It also fixes the trouble with aesv2 testing. I have written a couple of
test vectors both encrypt and decrypt from the RFC3602.

Finally, I have commented crypt filters implementation support. I will
adjust it to work with new crypt module interface.

Greetings.

# 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: ed0b43425a60a0024840920714f513c69bc365b8
# timestamp: 2008-12-23 19:09:09 +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;
 }
 

=== 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

=== 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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
+z14ZJlAjSgFDdVP/4u5IpwoSEcFuoCA

--- End Message ---

reply via email to

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