Add crypto support to eet.
authorcedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 13 Nov 2008 16:31:13 +0000 (16:31 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 13 Nov 2008 16:31:13 +0000 (16:31 +0000)
GNUTLS support by Arnaud de Turckheim <quarium@gmail.com>.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/eet@37603 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

AUTHORS
configure.ac
src/bin/eet_main.c
src/lib/Eet.h
src/lib/Eet_private.h
src/lib/Makefile.am
src/lib/eet_data.c
src/lib/eet_image.c
src/lib/eet_lib.c
src/tests/eet_suite.c

diff --git a/AUTHORS b/AUTHORS
index c491082..394dcce 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,3 +1,4 @@
 The Rasterman (Carsten Haitzler) <raster@rasterman.com>
 David Goodlad <dgoodlad@gmail.com>
 Cedric Bail <cedric.bail@free.fr>
+Arnaud de Turckheim <quarium@gmail.com>
index 0dbf64a..39e848c 100644 (file)
@@ -29,13 +29,15 @@ AC_SUBST(version_info)
 
 case "$host_os" in
    mingw* | cegcc*)
+      want_gnutls="no"
       want_openssl="no"
-      want_cypher="no"
+      want_cipher="no"
       want_signature="no"
       ;;
    *)
+      want_gnutls="auto"
       want_openssl="auto"
-      want_cypher="yes"
+      want_cipher="yes"
       want_signature="yes"
       ;;
 esac
@@ -64,6 +66,15 @@ else
    AC_DEFINE(EET_OLD_EET_FILE_FORMAT, 0, [support old eet file format])
 fi
 
+# Gnutls support
+
+AC_ARG_ENABLE([gnutls],
+   [AC_HELP_STRING([--disable-gnutls], [disable gnutls eet support])],
+   [want_gnutls=$enableval]
+)
+AC_MSG_CHECKING([whether to use Gnutls])
+AC_MSG_RESULT([${want_gnutls}])
+
 # Openssl support
 
 AC_ARG_ENABLE([openssl],
@@ -75,12 +86,12 @@ AC_MSG_RESULT([${want_openssl}])
 
 # Cryptography support
 
-AC_ARG_ENABLE([cypher],
-   [AC_HELP_STRING([--disable-cypher], [disable cypher support for eet API])],
-   [want_cypher=$enableval]
+AC_ARG_ENABLE([cipher],
+   [AC_HELP_STRING([--disable-cipher], [disable cipher support for eet API])],
+   [want_cipher=$enableval]
 )
-AC_MSG_CHECKING([whether to use cypher])
-AC_MSG_RESULT([${want_cypher}])
+AC_MSG_CHECKING([whether to use cipher])
+AC_MSG_RESULT([${want_cipher}])
 
 AC_ARG_ENABLE([signature],
    [AC_HELP_STRING([--disable-signature], [disable signature file support for eet])],
@@ -152,6 +163,20 @@ AC_SUBST(EET_LIBS)
 PKG_CHECK_MODULES(EINA, [eina-0])
 requirement_eet="eina-0 ${requirement_eet}"
 
+# Gnutls library
+have_gnutls="no"
+if test "x${want_gnutls}" = "xyes" -o "x${want_gnutls}" = "xauto" ; then
+   PKG_CHECK_MODULES(GNUTLS, [gnutls >= 1.7.6],
+      [
+       have_gnutls="yes"
+       AC_DEFINE(HAVE_GNUTLS, 1, [Have Gnutls support])
+       requirement_eet="gnutls ${requirement_eet}"
+      ],
+      [
+       have_gnutls="no"
+      ])
+fi
+
 # Openssl library
 have_openssl="no"
 if test "x${want_openssl}" = "xyes" -o "x${want_openssl}" = "xauto" ; then
@@ -164,17 +189,23 @@ if test "x${want_openssl}" = "xyes" -o "x${want_openssl}" = "xauto" ; then
       [have_openssl="no"])
 fi
 
-have_cypher="no"
-if test "x${have_openssl}" = "xyes" -a "x${want_cypher}" = "xyes" ; then
-   have_cypher="yes"
-   AC_DEFINE(HAVE_CYPHER, 1, [Have cypher support built in eet])
+have_cipher="no"
+if test "x${have_gnutls}" = "xyes" -a "x${want_cipher}" = "xyes" ; then
+   have_cipher="yes"
+   AC_DEFINE(HAVE_CIPHER, 1, [Have cipher support built in eet])
+elif test "x${have_openssl}" = "xyes" -a "x${want_cipher}" = "xyes" ; then
+   have_cipher="yes"
+   AC_DEFINE(HAVE_CIPHER, 1, [Have cipher support built in eet])
 fi
 
-AC_MSG_CHECKING(whether to activate cypher support in eet)
-AC_MSG_RESULT(${have_cypher})
+AC_MSG_CHECKING(whether to activate cipher support in eet)
+AC_MSG_RESULT(${have_cipher})
 
 have_signature="no"
-if test "x${have_openssl}" = "xyes" -a "x${want_signature}" = "xyes" ; then
+if test "x${have_gnutls}" = "xyes" -a "x${want_signature}" = "xyes" ; then
+   have_signature="yes"
+   AC_DEFINE(HAVE_SIGNATURE, 1, [Have signature support for eet file])
+elif test "x${have_openssl}" = "xyes" -a "x${want_signature}" = "xyes" ; then
    have_signature="yes"
    AC_DEFINE(HAVE_SIGNATURE, 1, [Have signature support for eet file])
 fi
@@ -313,8 +344,9 @@ echo "------------------------------------------------------------------------"
 echo
 echo "Configuration Options Summary:"
 echo
+echo "  Gnutls...............: ${have_gnutls}"
 echo "  Openssl..............: ${have_openssl}"
-echo "    Cypher support.....: ${have_cypher}"
+echo "    Cipher support.....: ${have_cipher}"
 echo "    Signature..........: ${have_signature}"
 echo
 echo "  Documentation........: ${enable_doc}"
index 76360f9..114fffe 100644 (file)
@@ -41,7 +41,7 @@ do_eet_list(const char *file)
 }
 
 static void
-do_eet_extract(const char *file, const char *key, const char *out)
+do_eet_extract(const char *file, const char *key, const char *out, const char *crypto_key)
 {
    Eet_File *ef;
    void *data;
@@ -54,7 +54,7 @@ do_eet_extract(const char *file, const char *key, const char *out)
        printf("cannot open for reading: %s\n", file);
        exit(-1);
      }
-   data = eet_read(ef, key, &size);
+   data = eet_read_cipher(ef, key, &size, crypto_key);
    if (!data)
      {
        printf("cannot read key %s\n", key);
@@ -83,7 +83,7 @@ do_eet_decode_dump(void *data, const char *str)
 }
 
 static void
-do_eet_decode(const char *file, const char *key, const char *out)
+do_eet_decode(const char *file, const char *key, const char *out, const char *crypto_key)
 {
    Eet_File *ef;
    FILE *f;
@@ -100,7 +100,7 @@ do_eet_decode(const char *file, const char *key, const char *out)
        printf("cannot open %s\n", out);
        exit(-1);
      }
-   if (!eet_data_dump(ef, key, do_eet_decode_dump, f))
+   if (!eet_data_dump_cipher(ef, key, crypto_key, do_eet_decode_dump, f))
      {
        printf("cannot write to %s\n", out);
        exit(-1);
@@ -110,7 +110,7 @@ do_eet_decode(const char *file, const char *key, const char *out)
 }
 
 static void
-do_eet_insert(const char *file, const char *key, const char *out, int compress)
+do_eet_insert(const char *file, const char *key, const char *out, int compress, const char *crypto_key)
 {
    Eet_File *ef;
    void *data;
@@ -146,13 +146,13 @@ do_eet_insert(const char *file, const char *key, const char *out, int compress)
        exit(-1);
      }
    fclose(f);
-   eet_write(ef, key, data, size, compress);
+   eet_write_cipher(ef, key, data, size, compress, crypto_key);
    free(data);
    eet_close(ef);
 }
 
 static void
-do_eet_encode(const char *file, const char *key, const char *out, int compress)
+do_eet_encode(const char *file, const char *key, const char *out, int compress, const char *crypto_key)
 {
    Eet_File *ef;
    char *text;
@@ -189,7 +189,7 @@ do_eet_encode(const char *file, const char *key, const char *out, int compress)
        exit(-1);
      }
    fclose(f);
-   if (!eet_data_undump(ef, key, text, textlen, compress))
+   if (!eet_data_undump_cipher(ef, key, crypto_key, text, textlen, compress))
      {
         printf("cannot parse %s\n", out);
        exit(-1);
@@ -265,14 +265,14 @@ main(int argc, char **argv)
      {
        help:
        printf("Usage:\n"
-              "  eet -l FILE.EET                      list all keys in FILE.EET\n"
-              "  eet -x FILE.EET KEY OUT-FILE         extract data stored in KEY in FILE.EET and write to OUT-FILE\n"
-              "  eet -d FILE.EET KEY OUT-FILE         extract and decode data stored in KEY in FILE.EET and write to OUT-FILE\n"
-              "  eet -i FILE.EET KEY IN-FILE COMPRESS insert data to KEY in FILE.EET from IN-FILE and if COMPRESS is 1, compress it\n"
-              "  eet -e FILE.EET KEY IN-FILE COMPRESS insert and encode to KEY in FILE.EET from IN-FILE and if COMPRESS is 1, compress it\n"
-              "  eet -r FILE.EET KEY                  remove KEY in FILE.EET\n"
-              "  eet -c FILE.EET                      report and check the signature information of an eet file\n"
-              "  eet -s FILE.EET PRIVATE_KEY PUBLIC_KEY sign FILE.EET with PRIVATE_KEY and attach PUBLIC_KEY as it's certificate\n"
+              "  eet -l FILE.EET                                    list all keys in FILE.EET\n"
+              "  eet -x FILE.EET KEY OUT-FILE [CRYPTO_KEY]          extract data stored in KEY in FILE.EET and write to OUT-FILE\n"
+              "  eet -d FILE.EET KEY OUT-FILE [CRYPTO_KEY]          extract and decode data stored in KEY in FILE.EET and write to OUT-FILE\n"
+              "  eet -i FILE.EET KEY IN-FILE COMPRESS [CRYPTO_KEY]  insert data to KEY in FILE.EET from IN-FILE and if COMPRESS is 1, compress it\n"
+              "  eet -e FILE.EET KEY IN-FILE COMPRESS [CRYPTO_KEY]  insert and encode to KEY in FILE.EET from IN-FILE and if COMPRESS is 1, compress it\n"
+              "  eet -r FILE.EET KEY                                remove KEY in FILE.EET\n"
+              "  eet -c FILE.EET                                    report and check the signature information of an eet file\n"
+              "  eet -s FILE.EET PRIVATE_KEY PUBLIC_KEY             sign FILE.EET with PRIVATE_KEY and attach PUBLIC_KEY as it's certificate\n"
               );
        eet_shutdown();
        return -1;
@@ -287,19 +287,31 @@ main(int argc, char **argv)
      }
    else if ((!strcmp(argv[1], "-x")) && (argc > 4))
      {
-       do_eet_extract(argv[2], argv[3], argv[4]);
+        if (argc > 5)
+         do_eet_extract(argv[2], argv[3], argv[4], argv[5]);
+       else
+         do_eet_extract(argv[2], argv[3], argv[4], NULL);
      }
    else if ((!strcmp(argv[1], "-d")) && (argc > 4))
      {
-       do_eet_decode(argv[2], argv[3], argv[4]);
+        if (argc > 5)
+        do_eet_decode(argv[2], argv[3], argv[4], argv[5]);
+       else
+        do_eet_decode(argv[2], argv[3], argv[4], NULL);
      }
    else if ((!strcmp(argv[1], "-i")) && (argc > 5))
      {
-       do_eet_insert(argv[2], argv[3], argv[4], atoi(argv[5]));
+        if (argc > 6)
+         do_eet_insert(argv[2], argv[3], argv[4], atoi(argv[5]), argv[6]);
+       else
+         do_eet_insert(argv[2], argv[3], argv[4], atoi(argv[5]), NULL);
      }
    else if ((!strcmp(argv[1], "-e")) && (argc > 5))
      {
-       do_eet_encode(argv[2], argv[3], argv[4], atoi(argv[5]));
+        if (argc > 6)
+         do_eet_encode(argv[2], argv[3], argv[4], atoi(argv[5]), argv[6]);
+       else
+         do_eet_encode(argv[2], argv[3], argv[4], atoi(argv[5]), NULL);
      }
    else if ((!strcmp(argv[1], "-r")) && (argc > 3))
      {
index 606c7fe..4b34c06 100644 (file)
@@ -94,7 +94,10 @@ extern "C" {
        EET_ERROR_SIGNATURE_FAILED,
        EET_ERROR_INVALID_SIGNATURE,
        EET_ERROR_NOT_SIGNED,
-       EET_ERROR_NOT_IMPLEMENTED
+       EET_ERROR_NOT_IMPLEMENTED,
+       EET_ERROR_PRNG_NOT_SEEDED,
+       EET_ERROR_ENCRYPT_FAILED,
+       EET_ERROR_DECRYPT_FAILED
      } Eet_Error;
 
    typedef struct _Eet_File                  Eet_File;
@@ -358,6 +361,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *cipher_key);
    EAPI void *eet_read(Eet_File *ef, const char *name, int *size_ret);
 
    /**
@@ -406,6 +410,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int compress, const char *cipher_key);
    EAPI int eet_write(Eet_File *ef, const char *name, const void *data, int size, int compress);
 
    /**
@@ -503,6 +508,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_image_header_read_cipher(Eet_File *ef, const char *name, const char *key, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
    EAPI int eet_data_image_header_read(Eet_File *ef, const char *name, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
 
    /**
@@ -540,6 +546,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_image_read_cipher(Eet_File *ef, const char *name, const char *key, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
    EAPI void *eet_data_image_read(Eet_File *ef, const char *name, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
 
    /**
@@ -579,7 +586,8 @@ extern "C" {
     *
     * @since 1.0.2
     */
-  EAPI int eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
+   EAPI int eet_data_image_read_to_surface_cipher(Eet_File *ef, const char *name, const char *key, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
+   EAPI int eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
 
    /**
     * Write image data to the named key in an eet file.
@@ -613,6 +621,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_image_write_cipher(Eet_File *ef, const char *name, const char *key, const void *data, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy);
    EAPI int eet_data_image_write(Eet_File *ef, const char *name, const void *data, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy);
 
    /**
@@ -648,6 +657,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_image_header_decode_cipher(const void *data, const char *key, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
    EAPI int eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
 
    /**
@@ -685,6 +695,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_image_decode_cipher(const void *data, const char *key, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
    EAPI void *eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy);
 
    /**
@@ -724,6 +735,7 @@ extern "C" {
     *
     * @since 1.0.2
     */
+   EAPI int eet_data_image_decode_to_surface_cipher(const void *data, const char *key, int size, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
    EAPI int eet_data_image_decode_to_surface(const void *data, int size, unsigned int src_x, unsigned int src_y, unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride, int *alpha, int *compress, int *quality, int *lossy);
 
    /**
@@ -757,6 +769,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_image_encode_cipher(const void *data, const char *key, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy, int *size_ret);
    EAPI void *eet_data_image_encode(const void *data, int *size_ret, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy);
 
 /***************************************************************************/
@@ -986,6 +999,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key);
    EAPI void *eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name);
 
    /**
@@ -1002,6 +1016,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key, const void *data, int compress);
    EAPI int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress);
 
    /**
@@ -1047,6 +1062,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_text_dump_cipher(const void *data_in, const char *key, int size_in, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
    EAPI int eet_data_text_dump(const void *data_in, int size_in, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
 
    /**
@@ -1063,6 +1079,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_text_undump_cipher(const char *text, const char *key, int textlen, int *size_ret);
    EAPI void *eet_data_text_undump(const char *text, int textlen, int *size_ret);
 
    /**
@@ -1082,6 +1099,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_dump_cipher(Eet_File *ef, const char *name, const char *key, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
    EAPI int eet_data_dump(Eet_File *ef, const char *name, void (*dumpfunc) (void *data, const char *str), void *dumpdata);
 
    /**
@@ -1102,6 +1120,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI int eet_data_undump_cipher(Eet_File *ef, const char *name, const char *key, const char *text, int textlen, int compress);
    EAPI int eet_data_undump(Eet_File *ef, const char *name, const char *text, int textlen, int compress);
 
    /**
@@ -1128,6 +1147,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd, const void *data_in, const char *key, int size_in);
    EAPI void *eet_data_descriptor_decode(Eet_Data_Descriptor *edd, const void *data_in, int size_in);
 
    /**
@@ -1156,6 +1176,7 @@ extern "C" {
     *
     * @since 1.0.0
     */
+   EAPI void *eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd, const void *data_in, const char *key, int *size_ret);
    EAPI void *eet_data_descriptor_encode(Eet_Data_Descriptor *edd, const void *data_in, int *size_ret);
 
    /**
index 617ca10..acbd981 100644 (file)
 # include <config.h>
 #endif
 
+#ifdef HAVE_GNUTLS
+# include <gnutls/gnutls.h>
+# include <gnutls/x509.h>
+#else
 #ifdef HAVE_OPENSSL
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+#endif
 #endif
 
 typedef struct _Eet_String              Eet_String;
@@ -67,8 +72,13 @@ struct _Eet_Key
 {
    int          references;
 #ifdef HAVE_SIGNATURE
+# ifdef HAVE_GNUTLS
+   gnutls_x509_crt_t           certificate;
+   gnutls_x509_privkey_t       private_key;
+# else
    X509               *certificate;
    EVP_PKEY    *private_key;
+# endif
 #endif
 };
 
@@ -86,8 +96,8 @@ int   _eet_hash_gen(const char *key, int hash_size);
 const void* eet_identity_check(const void *data_base, unsigned int data_length,
                               const void *signature_base, unsigned int signature_length,
                               int *x509_length);
-Eet_Error eet_cypher(void *data, unsigned int size, const char *key, unsigned int length);
-Eet_Error eet_decypher(void *data, unsigned int size, const char *key, unsigned int length);
+Eet_Error eet_cipher(const void *data, unsigned int size, const char *key, unsigned int length, void **result, unsigned int *result_length);
+Eet_Error eet_decipher(const void *data, unsigned int size, const char *key, unsigned int length, void **result, unsigned int *result_length);
 Eet_Error eet_identity_sign(FILE *fp, Eet_Key *key);
 void eet_identity_unref(Eet_Key *key);
 void eet_identity_ref(Eet_Key *key);
index c93b86b..e24d080 100644 (file)
@@ -13,7 +13,8 @@ AM_CPPFLAGS = \
 @EET_CPPFLAGS@ \
 @EFL_EET_BUILD@ \
 @EFL_COVERAGE_CFLAGS@ \
-@OPENSSL_CFLAGS@
+@OPENSSL_CFLAGS@ \
+@GNUTLS_CFLAGS@
 
 include_HEADERS = Eet.h
 
@@ -23,12 +24,12 @@ libeet_la_SOURCES  = \
 eet_lib.c \
 eet_data.c \
 eet_image.c \
-eet_cypher.c \
+eet_cipher.c \
 eet_dictionary.c \
 eet_utils.c
 
 libeet_la_CFLAGS = @EET_CFLAGS@ @DEBUG_CFLAGS@
-libeet_la_LIBADD = @OPENSSL_LIBS@ @EFL_COVERAGE_LIBS@ @EET_LIBS@ @EINA_LIBS@ @EVIL_LIBS@ -lz -ljpeg -lm
+libeet_la_LIBADD = @GNUTLS_LIBS@ @OPENSSL_LIBS@ @EFL_COVERAGE_LIBS@ @EET_LIBS@ @EINA_LIBS@ @EVIL_LIBS@ -lz -ljpeg -lm
 libeet_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info @version_info@
 
 EXTRA_DIST = Eet_private.h
index 19b4bc3..474f9c1 100644 (file)
@@ -1190,21 +1190,22 @@ eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
 }
 
 EAPI void *
-eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
+eet_data_read_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key)
 {
    const Eet_Dictionary *ed = NULL;
-   const void           *data;
+   const void           *data = NULL;
    void                 *data_dec;
-   int                   size;
    int                   required_free = 0;
+   int                   size;
 
    ed = eet_dictionary_get(ef);
 
-   data = eet_read_direct(ef, name, &size);
+   if (!key)
+     data = eet_read_direct(ef, name, &size);
    if (!data)
      {
        required_free = 1;
-       data = eet_read(ef, name, &size);
+       data = eet_read_cipher(ef, name, &size, key);
        if (!data) return NULL;
      }
 
@@ -1215,8 +1216,14 @@ eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
    return data_dec;
 }
 
+EAPI void *
+eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
+{
+   return eet_data_read_cipher(ef, edd, name, NULL);
+}
+
 EAPI int
-eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
+eet_data_write_cipher(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const char *key, const void *data, int compress)
 {
    Eet_Dictionary       *ed;
    void                 *data_enc;
@@ -1227,11 +1234,17 @@ eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const v
 
    data_enc = _eet_data_descriptor_encode(ed, edd, data, &size);
    if (!data_enc) return 0;
-   val = eet_write(ef, name, data_enc, size, compress);
+   val = eet_write_cipher(ef, name, data_enc, size, compress, key);
    free(data_enc);
    return val;
 }
 
+EAPI int
+eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
+{
+   return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
+}
+
 typedef struct _Eet_Free        Eet_Free;
 struct _Eet_Free
 {
@@ -3028,24 +3041,25 @@ eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element
 }
 
 EAPI int
-eet_data_dump(Eet_File *ef,
-             const char *name,
-             void (*dumpfunc) (void *data, const char *str),
-             void *dumpdata)
+eet_data_dump_cipher(Eet_File *ef,
+                    const char *name, const char *key,
+                    void (*dumpfunc) (void *data, const char *str),
+                    void *dumpdata)
 {
    const Eet_Dictionary *ed = NULL;
-   const void          *data;
+   const void          *data = NULL;
    int                  ret = 0;
    int                  required_free = 0;
    int                  size;
 
    ed = eet_dictionary_get(ef);
 
-   data = eet_read_direct(ef, name, &size);
+   if (!key)
+     data = eet_read_direct(ef, name, &size);
    if (!data)
      {
        required_free = 1;
-       data = eet_read(ef, name, &size);
+       data = eet_read_cipher(ef, name, &size, key);
        if (!data) return 0;
      }
 
@@ -3059,6 +3073,46 @@ eet_data_dump(Eet_File *ef,
    return ret;
 }
 
+EAPI int
+eet_data_dump(Eet_File *ef,
+             const char *name,
+             void (*dumpfunc) (void *data, const char *str),
+             void *dumpdata)
+{
+   return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
+}
+
+
+EAPI int
+eet_data_text_dump_cipher(const void *data_in,
+                         const char *key, int size_in,
+                         void (*dumpfunc) (void *data, const char *str),
+                         void *dumpdata)
+{
+   void *ret = NULL;
+   unsigned int ret_len = 0;
+
+   if (data_in && key)
+     {
+       if (eet_decipher(data_in, size_in, key, strlen(key), &ret, &ret_len))
+        {
+          if (ret) free(ret);
+          return 1;
+        }
+       if (_eet_data_descriptor_decode(NULL, NULL, ret, ret_len, 0,
+                                      dumpfunc, dumpdata))
+        {
+          free(ret);
+          return 1;
+        }
+       free(ret);
+       return 0;
+     }
+   if (_eet_data_descriptor_decode(NULL, NULL, data_in, size_in, 0,
+                                  dumpfunc, dumpdata))
+     return 1;
+   return 0;
+}
 
 EAPI int
 eet_data_text_dump(const void *data_in,
@@ -3066,10 +3120,34 @@ eet_data_text_dump(const void *data_in,
                   void (*dumpfunc) (void *data, const char *str),
                   void *dumpdata)
 {
-   if (_eet_data_descriptor_decode(NULL, NULL, data_in, size_in, 0,
-                                  dumpfunc, dumpdata))
-     return 1;
-   return 0;
+   return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
+}
+
+EAPI void *
+eet_data_text_undump_cipher(const char *text,
+                           const char *key,
+                           int textlen,
+                           int *size_ret)
+{
+   void *ret = NULL;
+   void *cyphered = NULL;
+   unsigned int cyphered_len;
+
+   ret = _eet_data_dump_parse(NULL, size_ret, text, textlen);
+   if (ret && key)
+     {
+       if (eet_cipher(ret, *size_ret, key, strlen(key), &cyphered, &cyphered_len))
+        {
+          if (cyphered) free(cyphered);
+          size_ret = 0;
+          free(ret);
+          return NULL;
+        }
+       free(ret);
+       *size_ret = cyphered_len;
+       ret = cyphered;
+     }
+   return ret;
 }
 
 EAPI void *
@@ -3077,15 +3155,16 @@ eet_data_text_undump(const char *text,
                     int textlen,
                     int *size_ret)
 {
-   return _eet_data_dump_parse(NULL, size_ret, text, textlen);
+   return eet_data_text_undump_cipher(text, NULL, textlen, size_ret);
 }
 
 EAPI int
-eet_data_undump(Eet_File *ef,
-               const char *name,
-               const char *text,
-               int textlen,
-               int compress)
+eet_data_undump_cipher(Eet_File *ef,
+                      const char *name,
+                      const char *key,
+                      const char *text,
+                      int textlen,
+                      int compress)
 {
    Eet_Dictionary       *ed;
    void                 *data_enc;
@@ -3096,18 +3175,53 @@ eet_data_undump(Eet_File *ef,
 
    data_enc = _eet_data_dump_parse(ed, &size, text, textlen);
    if (!data_enc) return 0;
-   val = eet_write(ef, name, data_enc, size, compress);
+   val = eet_write_cipher(ef, name, data_enc, size, compress, key);
    free(data_enc);
    return val;
 }
 
+EAPI int
+eet_data_undump(Eet_File *ef,
+               const char *name,
+               const char *text,
+               int textlen,
+               int compress)
+{
+   return eet_data_undump_cipher(ef, name, NULL, text, textlen, compress);
+}
+
+EAPI void *
+eet_data_descriptor_decode_cipher(Eet_Data_Descriptor *edd,
+                                 const void *data_in,
+                                 const char *key,
+                                 int size_in)
+{
+   void *deciphered = NULL;
+   unsigned int deciphered_len = 0;
+   void *ret;
+
+   if (key && data_in)
+     {
+       if (eet_decipher(data_in, size_in, key, strlen(key), &deciphered, &deciphered_len))
+        {
+          if (deciphered) free(deciphered);
+          return NULL;
+        }
+       ret = _eet_data_descriptor_decode(NULL, edd, deciphered, deciphered_len, 0,
+                                        NULL, NULL);
+       free(deciphered);
+       return ret;
+     }
+   return _eet_data_descriptor_decode(NULL, edd, data_in, size_in, 0,
+                                      NULL, NULL);
+}
+
 EAPI void *
 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
                           const void *data_in,
                           int size_in)
 {
-   return _eet_data_descriptor_decode(NULL, edd, data_in, size_in, 0,
-                                      NULL, NULL);
+   return eet_data_descriptor_decode_cipher(edd, data_in, NULL, size_in);
 }
 
 static void *
@@ -3161,9 +3275,36 @@ _eet_data_descriptor_encode(Eet_Dictionary *ed,
 }
 
 EAPI void *
+eet_data_descriptor_encode_cipher(Eet_Data_Descriptor *edd,
+                                 const void *data_in,
+                                 const char *key,
+                                 int *size_ret)
+{
+   void *ret = NULL;
+   void *ciphered = NULL;
+   unsigned int ciphered_len = 0;
+
+   ret = _eet_data_descriptor_encode(NULL, edd, data_in, size_ret);
+   if (key && ret)
+     {
+       if (eet_cipher(ret, *size_ret, key, strlen(key), &ciphered, &ciphered_len))
+        {
+          if (ciphered) free(ciphered);
+          size_ret = 0;
+          free(ret);
+          return NULL;
+        }
+       free(ret);
+       *size_ret = ciphered_len;
+       ret = ciphered;
+     }
+   return ret;
+}
+
+EAPI void *
 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
                           const void *data_in,
                           int *size_ret)
 {
-   return _eet_data_descriptor_encode(NULL, edd, data_in, size_ret);
+   return eet_data_descriptor_encode_cipher(edd, data_in, NULL, size_ret);
 }
index eb1f171..43b0a97 100644 (file)
@@ -906,9 +906,9 @@ eet_data_image_jpeg_alpha_convert(int *size, const void *data, unsigned int w, u
 }
 
 EAPI int
-eet_data_image_write(Eet_File *ef, const char *name,
-                    const void *data, unsigned int w, unsigned int h, int alpha,
-                    int compress, int quality, int lossy)
+eet_data_image_write_cipher(Eet_File *ef, const char *name, const char *key,
+                           const void *data, unsigned int w, unsigned int h, int alpha,
+                           int compress, int quality, int lossy)
 {
    void *d = NULL;
    int size = 0;
@@ -918,32 +918,41 @@ eet_data_image_write(Eet_File *ef, const char *name,
      {
        int v;
 
-       v = eet_write(ef, name, d, size, 0);
+       v = eet_write_cipher(ef, name, d, size, 0, key);
        free(d);
        return v;
      }
    return 0;
 }
 
+EAPI int
+eet_data_image_write(Eet_File *ef, const char *name,
+                    const void *data, unsigned int w, unsigned int h, int alpha,
+                    int compress, int quality, int lossy)
+{
+   return eet_data_image_write_cipher(ef, name, NULL, data, w, h, alpha, compress, quality, lossy);
+}
+
+
 EAPI void *
-eet_data_image_read(Eet_File *ef, const char *name,
-                   unsigned int *w, unsigned int *h, int *alpha,
-                   int *compress, int *quality, int *lossy)
+eet_data_image_read_cipher(Eet_File *ef, const char *name, const char *key,
+                          unsigned int *w, unsigned int *h, int *alpha,
+                          int *compress, int *quality, int *lossy)
 {
    unsigned int *d = NULL;
-   void                *data;
-   int          size;
+   void                *data = NULL;
    int          free_data = 0;
+   int          size;
 
-
-   data = (void *)eet_read_direct(ef, name, &size);
+   if (!key)
+     data = (void *)eet_read_direct(ef, name, &size);
    if (!data)
      {
-       data = eet_read(ef, name, &size);
+        data = eet_read_cipher(ef, name, &size, key);
        free_data = 1;
+       if (!data) return NULL;
      }
 
-   if (!data) return NULL;
    d = eet_data_image_decode(data, size, w, h, alpha, compress, quality, lossy);
 
    if (free_data)
@@ -952,25 +961,33 @@ eet_data_image_read(Eet_File *ef, const char *name,
    return d;
 }
 
+EAPI void *
+eet_data_image_read(Eet_File *ef, const char *name,
+                   unsigned int *w, unsigned int *h, int *alpha,
+                   int *compress, int *quality, int *lossy)
+{
+   return eet_data_image_read_cipher(ef, name, NULL, w, h, alpha, compress, quality, lossy);
+}
+
 EAPI int
-eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_x, unsigned int src_y,
-                              unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
-                              int *alpha, int *compress, int *quality, int *lossy)
+eet_data_image_read_to_surface_cipher(Eet_File *ef, const char *name, const char *key, unsigned int src_x, unsigned int src_y,
+                                     unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
+                                     int *alpha, int *compress, int *quality, int *lossy)
 {
-   void                *data;
-   int          size;
+   void                *data = NULL;
    int          free_data = 0;
    int          res = 1;
+   int          size;
 
-
-   data = (void *)eet_read_direct(ef, name, &size);
+   if (!key)
+     data = (void *)eet_read_direct(ef, name, &size);
    if (!data)
      {
-       data = eet_read(ef, name, &size);
-       free_data = 1;
+       data = eet_read_cipher(ef, name, &size, key);
+       free_data = 1;
+       if (!data) return 0;
      }
 
-   if (!data) return 0;
    res = eet_data_image_decode_to_surface(data, size, src_x, src_y, d, w, h, row_stride, alpha, compress, quality, lossy);
 
    if (free_data)
@@ -980,23 +997,32 @@ eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_
 }
 
 EAPI int
-eet_data_image_header_read(Eet_File *ef, const char *name,
-                          unsigned int *w, unsigned int *h, int *alpha,
-                          int *compress, int *quality, int *lossy)
+eet_data_image_read_to_surface(Eet_File *ef, const char *name, unsigned int src_x, unsigned int src_y,
+                              unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
+                              int *alpha, int *compress, int *quality, int *lossy)
+{
+   return eet_data_image_read_to_surface_cipher(ef, name, NULL, src_x, src_y, d, w, h, row_stride, alpha, compress, quality, lossy);
+}
+
+EAPI int
+eet_data_image_header_read_cipher(Eet_File *ef, const char *name, const char *key,
+                                 unsigned int *w, unsigned int *h, int *alpha,
+                                 int *compress, int *quality, int *lossy)
 {
    void        *data = NULL;
    int size = 0;
-   int d;
    int free_data = 0;
+   int d;
 
-   data = (void *)eet_read_direct(ef, name, &size);
+   if (!key)
+     data = (void *)eet_read_direct(ef, name, &size);
    if (!data)
      {
-       data = eet_read(ef, name, &size);
+        data = eet_read_cipher(ef, name, &size, key);
        free_data = 1;
+       if (!data) return 0;
      }
 
-   if (!data) return 0;
    d = eet_data_image_header_decode(data, size, w, h, alpha, compress, quality, lossy);
    if (free_data)
      free(data);
@@ -1004,10 +1030,21 @@ eet_data_image_header_read(Eet_File *ef, const char *name,
    return d;
 }
 
+EAPI int
+eet_data_image_header_read(Eet_File *ef, const char *name,
+                          unsigned int *w, unsigned int *h, int *alpha,
+                          int *compress, int *quality, int *lossy)
+{
+   return eet_data_image_header_read_cipher(ef, name, NULL, w, h, alpha, compress, quality, lossy);
+}
+
+
 EAPI void *
-eet_data_image_encode(const void *data, int *size_ret, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy)
+eet_data_image_encode_cipher(const void *data, const char *key, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy, int *size_ret)
 {
    void *d = NULL;
+   void *ciphered_d = NULL;
+   unsigned int ciphered_sz = 0;
    int size = 0;
 
    if (lossy == 0)
@@ -1027,14 +1064,45 @@ eet_data_image_encode(const void *data, int *size_ret, unsigned int w, unsigned
        else
          d = eet_data_image_jpeg_alpha_convert(&size, data, w, h, alpha, quality);
      }
+   if (key)
+     {
+       if(!eet_cipher(d, size, key, strlen(key), &ciphered_d, &ciphered_sz))
+        {
+          if (d) free(d);
+          d = ciphered_d;
+          size = ciphered_sz;
+        }
+       else
+        if (ciphered_d) free(ciphered_d);
+     }
+
    if (size_ret) *size_ret = size;
    return d;
 }
 
+EAPI void *
+eet_data_image_encode(const void *data, int *size_ret, unsigned int w, unsigned int h, int alpha, int compress, int quality, int lossy)
+{
+   return eet_data_image_encode_cipher(data, NULL, w, h, alpha, compress, quality, lossy, size_ret);
+}
+
 EAPI int
-eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
+eet_data_image_header_decode_cipher(const void *data, const char *key, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
 {
    int header[8];
+   void *deciphered_d = NULL;
+   unsigned int deciphered_sz = 0;
+
+   if (key)
+     {
+       if (!eet_decipher(data, size, key, strlen(key), &deciphered_d, &deciphered_sz))
+        {
+          data = deciphered_d;
+          size = deciphered_sz;
+        }
+       else
+        if (deciphered_d) free(deciphered_d);
+     }
 
    if (words_bigendian == -1)
      {
@@ -1115,6 +1183,12 @@ eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsign
    return 0;
 }
 
+EAPI int
+eet_data_image_header_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
+{
+   return eet_data_image_header_decode_cipher(data, NULL, size, w, h, alpha, compress, quality, lossy);
+}
+
 static void
 _eet_data_image_copy_buffer(const unsigned int *src, unsigned int src_x, unsigned int src_y, unsigned int src_w,
                            unsigned int *dst, unsigned int w, unsigned int h, unsigned int row_stride)
@@ -1229,11 +1303,24 @@ _eet_data_image_decode_inside(const void *data, int size, unsigned int src_x, un
 }
 
 EAPI void *
-eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
+eet_data_image_decode_cipher(const void *data, const char *key, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
 {
    unsigned int *d = NULL;
    unsigned int iw, ih;
    int ialpha, icompress, iquality, ilossy;
+   void *deciphered_d = NULL;
+   unsigned int deciphered_sz = 0;
+
+   if (key)
+     {
+       if (!eet_decipher(data, size, key, strlen(key), &deciphered_d, &deciphered_sz))
+        {
+          data = deciphered_d;
+          size = deciphered_sz;
+        }
+       else
+        if (deciphered_d) free(deciphered_d);
+     }
 
    /* All check are done during header decode, this simplify the code a lot. */
    if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress, &iquality, &ilossy))
@@ -1258,13 +1345,32 @@ eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int
    return d;
 }
 
+EAPI void *
+eet_data_image_decode(const void *data, int size, unsigned int *w, unsigned int *h, int *alpha, int *compress, int *quality, int *lossy)
+{
+   return eet_data_image_decode_cipher(data, NULL, size, w, h, alpha, compress, quality, lossy);
+}
+
 EAPI int
-eet_data_image_decode_to_surface(const void *data, int size, unsigned int src_x, unsigned int src_y,
-                                unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
-                                int *alpha, int *compress, int *quality, int *lossy)
+eet_data_image_decode_to_surface_cipher(const void *data, const char *key, int size, unsigned int src_x, unsigned int src_y,
+                                       unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
+                                       int *alpha, int *compress, int *quality, int *lossy)
 {
    unsigned int iw, ih;
    int ialpha, icompress, iquality, ilossy;
+   void *deciphered_d = NULL;
+   unsigned int deciphered_sz = 0;
+
+   if (key)
+     {
+       if (!eet_decipher(data, size, key, strlen(key), &deciphered_d, &deciphered_sz))
+        {
+          data = deciphered_d;
+          size = deciphered_sz;
+        }
+       else
+        if (deciphered_d) free(deciphered_d);
+     }
 
    /* All check are done during header decode, this simplify the code a lot. */
    if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress, &iquality, &ilossy))
@@ -1284,3 +1390,11 @@ eet_data_image_decode_to_surface(const void *data, int size, unsigned int src_x,
 
    return 1;
 }
+
+EAPI int
+eet_data_image_decode_to_surface(const void *data, int size, unsigned int src_x, unsigned int src_y,
+                                unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride,
+                                int *alpha, int *compress, int *quality, int *lossy)
+{
+   return eet_data_image_decode_to_surface_cipher(data, NULL, size, src_x, src_y, d, w, h, row_stride, alpha, compress, quality, lossy);
+}
index cb3c535..bcdbf2e 100644 (file)
@@ -35,6 +35,10 @@ void *alloca (size_t);
 #include <unistd.h>
 #include <zlib.h>
 
+#ifdef HAVE_OPENSSL
+#include <openssl/err.h>
+#endif
+
 #ifdef HAVE_NETINET_IN_H
 # include <netinet/in.h>
 #endif
@@ -47,6 +51,11 @@ void *alloca (size_t);
 # include <Evil.h>
 #endif
 
+#ifdef HAVE_GNUTLS
+# include <gnutls/gnutls.h>
+# include <gcrypt.h>
+#endif
+
 #ifdef HAVE_OPENSSL
 # include <openssl/err.h>
 #endif
@@ -120,6 +129,7 @@ struct _Eet_File_Node
 
    unsigned char         free_name : 1;
    unsigned char         compression : 1;
+   unsigned char         ciphered : 1;
 };
 
 #if 0
@@ -132,7 +142,7 @@ int bytes_directory_entries; /* bytes of directory entries to follow */
 struct
 {
    int offset; /* bytes offset into file for data chunk */
-   int flags; /* flags - for now 0 = uncompressed, 1 = compressed */
+   int flags; /* flags - for now 0 = uncompressed and clear, 1 = compressed and clear, 2 = uncompressed and ciphered, 3 = compressed and ciphered */
    int size; /* size of the data chunk */
    int data_size; /* size of the (uncompressed) data chunk */
    int name_size; /* length in bytes of the name field */
@@ -459,14 +469,17 @@ eet_flush2(Eet_File *ef)
      {
         for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
           {
-             int        ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT];
+            unsigned int flag;
+             int ibuf[EET_FILE2_DIRECTORY_ENTRY_COUNT];
+
+            flag = (efn->ciphered << 1) | efn->compression;
 
              ibuf[0] = (int) htonl ((unsigned int) efn->offset);
              ibuf[1] = (int) htonl ((unsigned int) efn->size);
              ibuf[2] = (int) htonl ((unsigned int) efn->data_size);
              ibuf[3] = (int) htonl ((unsigned int) efn->name_offset);
              ibuf[4] = (int) htonl ((unsigned int) efn->name_size);
-             ibuf[5] = (int) htonl ((unsigned int) efn->compression);
+             ibuf[5] = (int) htonl ((unsigned int) flag);
 
              if (fwrite(ibuf, sizeof(ibuf), 1, ef->fp) != 1)
                goto write_error;
@@ -700,6 +713,30 @@ eet_init(void)
 
    if (eet_initcount > 1) return eet_initcount;
 
+#ifdef HAVE_GNUTLS
+   if (gnutls_global_init())
+     return --eet_initcount;
+   /* Before the library can be used, it must initialize itself. */
+   gcry_check_version(NULL);
+   /* Disable warning messages about problems with the secure memory subsystem.
+      This command should be run right after gcry_check_version. */
+   if (gcry_control(GCRYCTL_DISABLE_SECMEM_WARN))
+     {
+       gnutls_global_deinit();
+       return --eet_initcount;
+     }
+   /* This command is used to allocate a pool of secure memory and thus
+      enabling the use of secure memory. It also drops all extra privileges the
+      process has (i.e. if it is run as setuid (root)). If the argument nbytes
+      is 0, secure memory will be disabled. The minimum amount of secure memory
+      allocated is currently 16384 bytes; you may thus use a value of 1 to
+      request that default size. */
+   if (gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0))
+     {
+       gnutls_global_deinit();
+       return --eet_initcount;
+     }
+#endif
 #ifdef HAVE_OPENSSL
    ERR_load_crypto_strings();
 #endif
@@ -717,6 +754,9 @@ eet_shutdown(void)
    if (eet_initcount > 0) return eet_initcount;
 
    eet_clearcache();
+#ifdef HAVE_GNUTLS
+   gnutls_global_deinit();
+#endif
 #ifdef HAVE_OPENSSL
    ERR_free_strings();
 #endif
@@ -850,6 +890,7 @@ eet_internal_read2(Eet_File *ef)
         int              name_offset;
         int              name_size;
         int              hash;
+       int              flag;
 
         /* out directory block is inconsistent - we have oveerun our */
         /* dynamic block buffer before we finished scanning dir entries */
@@ -863,7 +904,10 @@ eet_internal_read2(Eet_File *ef)
         GET_INT(efn->data_size, data, index);
         GET_INT(name_offset, data, index);
         GET_INT(name_size, data, index);
-        GET_INT(efn->compression, data, index);
+        GET_INT(flag, data, index);
+
+       efn->compression = flag & 0x1 ? 1 : 0;
+       efn->ciphered = flag & 0x2 ? 1 : 0;
 
 #define EFN_TEST(Test, Ef, Efn)                 \
         if (eet_test_close(Test, Ef))           \
@@ -1089,6 +1133,7 @@ eet_internal_read1(Eet_File *ef)
        EXTRACT_INT(name_size, p, indexn);
 
         efn->name_size = name_size;
+       efn->ciphered = 0;
 
        /* invalid size */
        if (eet_test_close(efn->size <= 0, ef))
@@ -1486,7 +1531,7 @@ eet_close(Eet_File *ef)
 }
 
 EAPI void *
-eet_read(Eet_File *ef, const char *name, int *size_ret)
+eet_read_cipher(Eet_File *ef, const char *name, int *size_ret, const char *cipher_key)
 {
    void                        *data = NULL;
    int                 size = 0;
@@ -1524,6 +1569,8 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
    /* uncompressed data */
    if (efn->compression == 0)
      {
+        void *data_deciphered = NULL;
+       unsigned int data_deciphered_sz = 0;
        /* if we alreayd have the data in ram... copy that */
        if (efn->data)
          memcpy(data, efn->data, efn->size);
@@ -1533,11 +1580,25 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
               free(data);
               return NULL;
            }
+        if (efn->ciphered && cipher_key)
+         {
+           if (eet_decipher(data, size, cipher_key, strlen(cipher_key), &data_deciphered, &data_deciphered_sz))
+             {
+               free(data);
+               if (data_deciphered) free(data_deciphered);
+               return NULL;
+             }
+           free(data);
+           data = data_deciphered;
+           size = data_deciphered_sz;
+         }
      }
    /* compressed data */
    else
      {
        void    *tmp_data;
+       void    *data_deciphered = NULL;
+       unsigned int data_deciphered_sz = 0;
        int     free_tmp = 0;
        int     compr_size = efn->size;
        uLongf  dlen;
@@ -1564,6 +1625,20 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
               }
          }
 
+       if (efn->ciphered && cipher_key)
+         {
+           if (eet_decipher(tmp_data, compr_size, cipher_key, strlen(cipher_key), &data_deciphered, &data_deciphered_sz))
+             {
+               free(data);
+               if (free_tmp) free(tmp_data);
+               if (data_deciphered) free(data_deciphered);
+               return NULL;
+             }
+           free(tmp_data);
+           tmp_data = data_deciphered;
+           compr_size = data_deciphered_sz;
+         }
+
        /* decompress it */
        dlen = size;
        if (uncompress((Bytef *)data, &dlen,
@@ -1584,6 +1659,12 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
    return data;
 }
 
+EAPI void *
+eet_read(Eet_File *ef, const char *name, int *size_ret)
+{
+   return eet_read_cipher(ef, name, size_ret, NULL);
+}
+
 EAPI const void *
 eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
 {
@@ -1619,7 +1700,8 @@ eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
    size = efn->data_size;
 
    /* uncompressed data */
-   if (efn->compression == 0)
+   if (efn->compression == 0
+       && efn->ciphered == 0)
      data = efn->data ? efn->data : ef->data + efn->offset;
    /* compressed data */
    else
@@ -1633,10 +1715,10 @@ eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
 }
 
 EAPI int
-eet_write(Eet_File *ef, const char *name, const void *data, int size, int compress)
+eet_write_cipher(Eet_File *ef, const char *name, const void *data, int size, int compress, const char *cipher_key)
 {
    Eet_File_Node       *efn;
-   void                        *data2;
+   void                        *data2 = NULL;
    int                 exists_already = 0;
    int                 data_size;
    int                 hash;
@@ -1676,9 +1758,12 @@ eet_write(Eet_File *ef, const char *name, const void *data, int size, int compre
 
    data_size = compress ? 12 + ((size * 101) / 100) : size;
 
-   data2 = malloc(data_size);
-   if (!data2)
-     return 0;
+   if (compress || !cipher_key)
+     {
+       data2 = malloc(data_size);
+       if (!data2)
+        return 0;
+     }
 
    /* if we want to compress */
    if (compress)
@@ -1709,8 +1794,30 @@ eet_write(Eet_File *ef, const char *name, const void *data, int size, int compre
               data2 = data3;
          }
      }
-   if (!compress)
-     memcpy(data2, data, size);
+
+   if (cipher_key)
+     {
+       void *data_ciphered = NULL;
+       unsigned int data_ciphered_sz = 0;
+       const void *tmp;
+
+       tmp = data2 ? data2 : data;
+       if (!eet_cipher(tmp, data_size, cipher_key, strlen(cipher_key), &data_ciphered, &data_ciphered_sz))
+        {
+          if (data2) free(data2);
+          data2 = data_ciphered;
+          data_size = data_ciphered_sz;
+          size = (data_size > size) ? data_size : size;
+        }
+       else
+        {
+          if (data_ciphered) free(data_ciphered);
+          cipher_key = NULL;
+        }
+     }
+   else
+     if (!compress)
+       memcpy(data2, data, size);
 
    /* Does this node already exist? */
    for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
@@ -1719,6 +1826,7 @@ eet_write(Eet_File *ef, const char *name, const void *data, int size, int compre
        if ((efn->name) && (eet_string_match(efn->name, name)))
          {
             free(efn->data);
+            efn->ciphered = cipher_key ? 1 : 0;
             efn->compression = !!compress;
             efn->size = data_size;
             efn->data_size = size;
@@ -1743,6 +1851,7 @@ eet_write(Eet_File *ef, const char *name, const void *data, int size, int compre
        efn->next = ef->header->directory->nodes[hash];
        ef->header->directory->nodes[hash] = efn;
        efn->offset = -1;
+       efn->ciphered = cipher_key ? 1 : 0;
        efn->compression = !!compress;
        efn->size = data_size;
        efn->data_size = size;
@@ -1755,6 +1864,12 @@ eet_write(Eet_File *ef, const char *name, const void *data, int size, int compre
 }
 
 EAPI int
+eet_write(Eet_File *ef, const char *name, const void *data, int size, int compress)
+{
+   return eet_write_cipher(ef, name, data, size, compress, NULL);
+}
+
+EAPI int
 eet_delete(Eet_File *ef, const char *name)
 {
    Eet_File_Node       *efn;
index 9a75103..26ddd9e 100644 (file)
@@ -1275,6 +1275,60 @@ START_TEST(eet_identity_simple)
 }
 END_TEST
 
+START_TEST(eet_cipher_decipher_simple)
+{
+   const char *buffer = "Here is a string of data to save !";
+   const char *key = "This is a crypto key";
+   const char *key_bad = "This is another crypto key";
+   Eet_File *ef;
+   char *test;
+   char *file = strdup("/tmp/eet_suite_testXXXXXX");
+   int size;
+   int fd;
+
+   eet_init();
+
+   mktemp(file);
+   chdir("src/tests");
+
+   /* Crypt an eet file. */
+   ef = eet_open(file, EET_FILE_MODE_WRITE);
+   fail_if(!ef);
+
+   fail_if(!eet_write_cipher(ef, "keys/tests", buffer, strlen(buffer) + 1, 0, key));
+
+   eet_close(ef);
+
+   /* Decrypt an eet file. */
+   ef = eet_open(file, EET_FILE_MODE_READ);
+   fail_if(!ef);
+
+   test = eet_read_cipher(ef, "keys/tests", &size, key);
+   fail_if(!test);
+   fail_if(size != (int) strlen(buffer) + 1);
+
+   fail_if(memcmp(test, buffer, strlen(buffer) + 1) != 0);
+
+   eet_close(ef);
+
+   /* Decrypt an eet file. */
+   ef = eet_open(file, EET_FILE_MODE_READ);
+   fail_if(!ef);
+
+   test = eet_read_cipher(ef, "keys/tests", &size, key_bad);
+
+   if (size == (int) strlen(buffer) + 1)
+     fail_if(memcmp(test, buffer, strlen(buffer) + 1) == 0);
+
+   eet_close(ef);
+
+   fail_if(unlink(file) != 0);
+
+   eet_shutdown();
+}
+END_TEST
+
+
 Suite *
 eet_suite(void)
 {
@@ -1310,6 +1364,12 @@ eet_suite(void)
    suite_add_tcase(s, tc);
 #endif
 
+#ifdef HAVE_CIPHER
+   tc = tcase_create("Eet Cipher");
+   tcase_add_test(tc, eet_cipher_decipher_simple);
+   suite_add_tcase(s, tc);
+#endif
+
    return s;
 }