AM_CONDITIONAL(EET_ENABLE_TESTS, test "x${enable_tests}" = "xyes")
+dnl Openssl support
+want_openssl="auto"
+have_openssl="no"
+AC_ARG_ENABLE(openssl,
+ [AC_HELP_STRING([--disable-openssl], [disable openssl eet support])],
+ [ want_openssl=$enableval ]
+)
+if test "x$want_openssl" = "xyes" -o "x$want_openssl" = "xauto"; then
+ PKG_CHECK_MODULES(OPENSSL, openssl,
+ [
+ have_openssl="yes"
+ AC_DEFINE(HAVE_OPENSSL, 1, [Have Openssl support])
+ ],
+ [
+ if test "x$use_strict" = "xyes"; then
+ AC_MSG_ERROR([Openssl not found (strict dependencies checking)])
+ fi
+ ])
+fi
+
+dnl Crypto option
+want_cypher="yes"
+have_cypher="no"
+want_signature="yes"
+have_signature="no"
+
+AC_MSG_CHECKING(whether to activate cypher support in eet)
+AC_ARG_ENABLE(cypher,
+ [AC_HELP_STRING([--disable-cypher], [disable cypher support for eet API])],
+ [ want_cypher=$enableval ]
+)
+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])
+fi
+AC_MSG_RESULT($have_cypher)
+
+AC_MSG_CHECKING(whether to activate signature support in eet)
+AC_ARG_ENABLE(signature,
+ [AC_HELP_STRING([--disable-signature], [disable signature file support for eet])],
+ [ want_signature=$enableval ]
+)
+if 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
+AC_MSG_RESULT($have_signature)
+
dnl Coverage
AC_ARG_ENABLE(coverage,
echo
echo "Configuration Options Summary:"
echo
+echo " Openssl..............: ${have_openssl}"
+echo " Cypher support.....: ${have_cypher}"
+echo " Signature..........: ${have_signature}"
+
echo " Tests................: ${enable_tests}"
echo " Coverage.............: ${enable_coverage}"
echo
eet_close(ef);
}
+static void
+do_eet_check(const char *file)
+{
+ Eet_File *ef;
+ const void *der;
+ int der_length;
+
+ ef = eet_open(file, EET_FILE_MODE_READ);
+ if (!ef)
+ {
+ fprintf(stdout, "checking signature of `%s` failed\n", file);
+ exit(-1);
+ }
+
+ der = eet_identity_x509(ef, &der_length);
+
+ eet_identity_certificate_print(der, der_length, stdout);
+
+ eet_close(ef);
+}
+
+static void
+do_eet_sign(const char *file, const char *private_key, const char *public_key)
+{
+ Eet_File *ef;
+ Eet_Key *key;
+
+ ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
+ if (!ef)
+ {
+ fprintf(stdout, "cannot open for read+write: %s.\n", file);
+ exit(-1);
+ }
+
+ key = eet_identity_open(public_key, private_key, NULL);
+
+ fprintf(stdout, "Using the following key to sign `%s`.\n", file);
+ eet_identity_print(key, stdout);
+
+ eet_identity_set(ef, key);
+
+ eet_close(ef);
+}
+
int
main(int argc, char **argv)
{
" 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_shutdown();
return -1;
{
goto help;
}
+ else if ((!strcmp(argv[1], "-c")) && (argc > 2))
+ {
+ do_eet_check(argv[2]);
+ }
+ else if ((!strcmp(argv[1], "-s")) && (argc > 4))
+ {
+ do_eet_sign(argv[2], argv[3], argv[4]);
+ }
+ else
+ {
+ goto help;
+ }
eet_shutdown();
return 0;
}
#define _EET_H
#include <stdlib.h>
+#include <stdio.h>
#ifdef EAPI
# undef EAPI
EET_ERROR_WRITE_ERROR_FILE_TOO_BIG,
EET_ERROR_WRITE_ERROR_IO_ERROR,
EET_ERROR_WRITE_ERROR_OUT_OF_SPACE,
- EET_ERROR_WRITE_ERROR_FILE_CLOSED
+ EET_ERROR_WRITE_ERROR_FILE_CLOSED,
+ EET_ERROR_MMAP_FAILED,
+ EET_ERROR_X509_ENCODING_FAILED,
+ EET_ERROR_SIGNATURE_FAILED,
+ EET_ERROR_INVALID_SIGNATURE,
+ EET_ERROR_NOT_SIGNED,
+ EET_ERROR_NOT_IMPLEMENTED
} Eet_Error;
typedef struct _Eet_File Eet_File;
typedef struct _Eet_Dictionary Eet_Dictionary;
typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor;
+ typedef struct _Eet_Key Eet_Key;
typedef struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class;
*/
EAPI Eet_Error eet_close(Eet_File *ef);
+ /**
+ * Callback used to request if needed the password of a private key.
+ *
+ * @since 2.0.0
+ */
+ typedef int (*Eet_Key_Password_Callback)(char *buffer, int size, int rwflag, void *data);
+
+ /**
+ * Create an Eet_Key needed for signing an eet file.
+ *
+ * The certificate should provide the public that match the private key.
+ * No verification is done to ensure that.
+ *
+ * @since 2.0.0
+ */
+ EAPI Eet_Key* eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb);
+
+ /**
+ * Close and release all ressource used by an Eet_Key.
+ * An reference counter prevent it from being freed until all file using it are
+ * also closed.
+ *
+ * @since 2.0.0
+ */
+ EAPI void eet_identity_close(Eet_Key *key);
+
+ /**
+ * Set a key to sign a file
+ *
+ * @since 2.0.0
+ */
+ EAPI Eet_Error eet_identity_set(Eet_File *ef, Eet_Key *key);
+
+ /**
+ * Display both private and public key of an Eet_Key.
+ *
+ * @since 2.0.0
+ */
+ EAPI void eet_identity_print(Eet_Key *key, FILE *out);
+
+ /**
+ * Get the x509 der certificate associated with an Eet_File. Will return NULL
+ * if the file is not signed.
+ *
+ * @since 2.0.0
+ */
+ EAPI const void *eet_identity_x509(Eet_File *ef, int *der_length);
+
+ /**
+ * Display the x509 der certificate to out.
+ *
+ * @since 2.0.0
+ */
+ EAPI void eet_identity_certificate_print(const unsigned char *certificate, int der_length, FILE *out);
/**
* Return a handle to the shared string dictionary of the Eet file
# endif
#endif
+#include "config.h"
+
+#ifdef HAVE_OPENSSL
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#endif
+
typedef struct _Eet_String Eet_String;
struct _Eet_String
const char *end;
};
+struct _Eet_Key
+{
+ int references;
+#ifdef HAVE_SIGNATURE
+ X509 *certificate;
+ EVP_PKEY *private_key;
+#endif
+};
+
Eet_Dictionary *eet_dictionary_add(void);
void eet_dictionary_free(Eet_Dictionary *ed);
int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string);
int _eet_string_to_double_convert(const char *src, long long *m, long *e);
void _eet_double_to_string_convert(char des[128], double d);
+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_identity_sign(FILE *fp, Eet_Key *key);
+void eet_identity_unref(Eet_Key *key);
+void eet_identity_ref(Eet_Key *key);
+
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EVIL_CFLAGS@ \
-@COVERAGE_CFLAGS@
+@COVERAGE_CFLAGS@ \
+@OPENSSL_CFLAGS@
include_HEADERS = Eet.h
eet_lib.c \
eet_data.c \
eet_image.c \
+eet_cypher.c \
eet_dictionary.c \
eet_utils.c
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#ifdef HAVE_SIGNATURE
+# include <openssl/rsa.h>
+# include <openssl/objects.h>
+# include <openssl/err.h>
+# include <openssl/ssl.h>
+# include <openssl/dh.h>
+# include <openssl/dsa.h>
+#endif
+
+#include "Eet.h"
+#include "Eet_private.h"
+
+#define EET_MAGIC_SIGN 0x1ee74271
+
+EAPI Eet_Key*
+eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb)
+{
+#ifdef HAVE_SIGNATURE
+ EVP_PKEY *pkey = NULL;
+ X509 *cert = NULL;
+ Eet_Key *key;
+ FILE *fp;
+
+ /* Load the X509 certificate in memory. */
+ fp = fopen(certificate_file, "r");
+ if (!fp) return NULL;
+ cert = PEM_read_X509(fp, NULL, NULL, NULL);
+ fclose(fp);
+ if (!cert) return NULL;
+
+ /* Check the presence of the public key. Just in case. */
+ pkey = X509_get_pubkey(cert);
+ if (!pkey) goto on_error;
+
+ /* Load the private key in memory. */
+ fp = fopen(private_key_file, "r");
+ if (!fp) goto on_error;
+ pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
+ fclose(fp);
+ if (!pkey) goto on_error;
+
+ key = malloc(sizeof(Eet_Key));
+ if (!key) goto on_error;
+
+ key->references = 1;
+ key->certificate = cert;
+ key->private_key = pkey;
+
+ return key;
+
+ on_error:
+ if (cert) X509_free(cert);
+ if (pkey) EVP_PKEY_free(pkey);
+#endif
+ return NULL;
+}
+
+EAPI void
+eet_identity_print(Eet_Key *key, FILE *out)
+{
+#ifdef HAVE_SIGNATURE
+ RSA *rsa;
+ DSA *dsa;
+ DH *dh;
+
+ if (!key) return ;
+
+ rsa = EVP_PKEY_get1_RSA(key->private_key);
+ if (rsa)
+ {
+ fprintf(out, "Private key (RSA) :\n");
+ RSA_print_fp(out, rsa, 0);
+ }
+
+ dsa = EVP_PKEY_get1_DSA(key->private_key);
+ if (dsa)
+ {
+ fprintf(out, "Private key (DSA) :\n");
+ DSA_print_fp(out, dsa, 0);
+ }
+
+ dh = EVP_PKEY_get1_DH(key->private_key);
+ if (dh)
+ {
+ fprintf(out, "Private key (DH) :\n");
+ DHparams_print_fp(out, dh);
+ }
+
+ fprintf(out, "Public certificate :\n");
+ X509_print_fp(out, key->certificate);
+#else
+ fprintf(out, "You need to compile signature support in EET.\n");
+#endif
+}
+
+EAPI void
+eet_identity_close(Eet_Key *key)
+{
+#ifdef HAVE_SIGNATURE
+ if (key->references > 0) return ;
+
+ X509_free(key->certificate);
+ EVP_PKEY_free(key->private_key);
+ free(key);
+#endif
+}
+
+void
+eet_identity_ref(Eet_Key *key)
+{
+ if (key == NULL) return ;
+ key->references++;
+}
+
+void
+eet_identity_unref(Eet_Key *key)
+{
+ if (key == NULL) return ;
+ key->references--;
+ eet_identity_close(key);
+}
+
+Eet_Error
+eet_identity_sign(FILE *fp, Eet_Key *key)
+{
+#ifdef HAVE_SIGNATURE
+ unsigned char *x509_der = NULL;
+ void *sign = NULL;
+ void *data;
+ int head[3];
+ EVP_MD_CTX md_ctx;
+ struct stat st_buf;
+ Eet_Error err = EET_ERROR_NONE;
+ int sign_length;
+ int x509_length;
+ int fd;
+
+ /* A few check and flush pending write. */
+ if (!fp
+ || !key
+ || !key->certificate
+ || !key->private_key)
+ return EET_ERROR_BAD_OBJECT;
+
+ /* Get the file size. */
+ fd = fileno(fp);
+ if (fd < 0) return EET_ERROR_BAD_OBJECT;
+ if (fstat(fd, &st_buf) < 0) return EET_ERROR_MMAP_FAILED;
+
+ /* Map the file in memory. */
+ data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (data == MAP_FAILED) return EET_ERROR_MMAP_FAILED;
+
+ sign_length = EVP_PKEY_size(key->private_key);
+ sign = malloc(sign_length);
+ if (sign == NULL)
+ {
+ err = EET_ERROR_OUT_OF_MEMORY;
+ goto on_error;
+ }
+
+ /* Do the signature. */
+ EVP_SignInit(&md_ctx, EVP_sha1());
+ EVP_SignUpdate (&md_ctx, data, st_buf.st_size);
+ err = EVP_SignFinal (&md_ctx, sign, &sign_length, key->private_key);
+ if (err != 1)
+ {
+ ERR_print_errors_fp(stdout);
+ err = EET_ERROR_SIGNATURE_FAILED;
+ goto on_error;
+ }
+
+ /* Give me the der (binary form for X509). */
+ x509_length = i2d_X509(key->certificate, &x509_der);
+ if (x509_length < 0)
+ {
+ ERR_print_errors_fp(stdout);
+ err = EET_ERROR_X509_ENCODING_FAILED;
+ goto on_error;
+ }
+
+ /* Append the signature at the end of the file. */
+ head[0] = (int) htonl ((unsigned int) EET_MAGIC_SIGN);
+ head[1] = (int) htonl ((unsigned int) sign_length);
+ head[2] = (int) htonl ((unsigned int) x509_length);
+
+ if (fwrite(head, sizeof(head), 1, fp) != 1)
+ {
+ err = EET_ERROR_WRITE_ERROR;
+ goto on_error;
+ }
+ if (fwrite(sign, sign_length, 1, fp) != 1)
+ {
+ err = EET_ERROR_WRITE_ERROR;
+ goto on_error;
+ }
+ if (fwrite(x509_der, x509_length, 1, fp) != 1)
+ {
+ err = EET_ERROR_WRITE_ERROR;
+ goto on_error;
+ }
+
+ on_error:
+ if (x509_der) OPENSSL_free(x509_der);
+ if (sign != NULL) free(sign);
+ munmap(data, st_buf.st_size);
+ return err;
+#else
+ return EET_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+const void*
+eet_identity_check(const void *data_base, unsigned int data_length,
+ const void *signature_base, unsigned int signature_length,
+ int *x509_length)
+{
+#ifdef HAVE_SIGNATURE
+ const int *header = signature_base;
+ const unsigned char *sign;
+ const unsigned char *cert_der;
+ const unsigned char *tmp;
+ EVP_PKEY *pkey;
+ X509 *x509;
+ EVP_MD_CTX md_ctx;
+ int sign_length;
+ int cert_length;
+ int magic;
+ int err;
+
+ if (signature_length < sizeof(int) * 3) return NULL;
+
+ magic = ntohl(header[0]);
+ sign_length = ntohl(header[1]);
+ cert_length = ntohl(header[2]);
+
+ if (magic != EET_MAGIC_SIGN) return NULL;
+ if (sign_length + cert_length + sizeof(int) * 3 > signature_length) return NULL;
+
+ sign = signature_base + sizeof(int) * 3;
+ cert_der = sign + sign_length;
+
+ /* Strange but d2i_X509 seems to put 0 all over the place. */
+ tmp = alloca(cert_length);
+ memcpy((char*) tmp, cert_der, cert_length);
+ x509 = d2i_X509(NULL, &tmp, cert_length);
+ if (x509 == NULL) return NULL;
+
+ /* Get public key - eay */
+ pkey=X509_get_pubkey(x509);
+ if (pkey == NULL)
+ {
+ X509_free(x509);
+ return NULL;
+ }
+
+ /* Verify the signature */
+ EVP_VerifyInit(&md_ctx, EVP_sha1());
+ EVP_VerifyUpdate(&md_ctx, data_base, data_length);
+ err = EVP_VerifyFinal(&md_ctx, sign, sign_length, pkey);
+
+ X509_free(x509);
+ EVP_PKEY_free(pkey);
+
+ if (err != 1)
+ return NULL;
+
+ if (x509_length) *x509_length = cert_length;
+ return cert_der;
+#else
+ return NULL;
+#endif
+}
+
+EAPI void
+eet_identity_certificate_print(const unsigned char *certificate, int der_length, FILE *out)
+{
+#ifdef HAVE_SIGNATURE
+ const unsigned char *tmp;
+ X509 *x509;
+
+ if (certificate == NULL
+ || out == NULL
+ || der_length <= 0)
+ {
+ fprintf(out, "No certificate provided.\n");
+ return ;
+ }
+
+ /* Strange but d2i_X509 seems to put 0 all over the place. */
+ tmp = alloca(der_length);
+ memcpy((char*) tmp, certificate, der_length);
+ x509 = d2i_X509(NULL, &tmp, der_length);
+ if (x509 == NULL)
+ {
+ fprintf(out, "Not a valid certificate.\n");
+ return ;
+ }
+
+ fprintf(out, "Public certificate :\n");
+ X509_print_fp(out, x509);
+
+ X509_free(x509);
+#else
+ fprintf(out, "You need to compile signature support in EET.\n");
+#endif
+}
+
+Eet_Error
+eet_cypher(void *data, unsigned int size, const char *key, unsigned int length)
+{
+#ifdef HAVE_CYPHER
+#else
+ return EET_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+Eet_Error
+eet_decypher(void *data, unsigned int size, const char *key, unsigned int length)
+{
+#ifdef HAVE_CYPHER
+#else
+ return EET_ERROR_NOT_IMPLEMENTED;
+#endif
+}
FILE *fp;
FILE *readfp;
Eet_File_Header *header;
- const unsigned char *data;
Eet_Dictionary *ed;
+ Eet_Key *key;
+ const unsigned char *data;
+ const void *x509_der;
int magic;
int references;
Eet_File_Mode mode;
int data_size;
+ int x509_length;
time_t mtime;
unsigned char writes_pending : 1;
} dictionary[num_dictionary_entries];
/* now start the string stream. */
/* and right after them the data stream. */
+int magic_sign; /* Optional, only if the eet file is signed. */
+int signature_length; /* Signature length. */
+int x509_length; /* Public certificate that signed the file. */
+char signature[signature_length]; /* The signature. */
+char x509[x509_length]; /* The public certificate. */
#endif
#define EET_FILE2_HEADER_COUNT 3
return EET_ERROR_NONE;
if (ef->mode == EET_FILE_MODE_READ_WRITE && ef->fp == NULL)
{
+ int fd;
+
unlink(ef->path);
- ef->fp = fopen(ef->path, "wb");
+ fd = open(file, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
+ ef->fp = fdopen(fd, "wb");
if (!ef->fp) return EET_ERROR_NOT_WRITABLE;
fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC);
}
}
}
+ /* flush all write to the file. */
+ fflush(ef->fp);
+
+ /* append signature if required */
+ if (ef->key)
+ {
+ error = eet_identity_sign(ef->fp, ef->key);
+ if (error != EET_ERROR_NONE)
+ goto sign_error;
+ }
+
/* no more writes pending */
ef->writes_pending = 0;
ef->fp = NULL;
return EET_ERROR_WRITE_ERROR;
}
+ sign_error:
fclose(ef->fp);
ef->fp = NULL;
return EET_ERROR_WRITE_ERROR;
EAPI int
eet_init(void)
{
+#ifdef HAVE_OPENSSL
+ /* Just load the crypto library error strings,
+ * SSL_load_error_strings() loads the crypto AND the SSL ones */
+ /* SSL_load_error_strings();*/
+ static int call_once = 0;
+
+ if (call_once == 0)
+ {
+ call_once = 1;
+ ERR_load_crypto_strings();
+ }
+
+#endif
return ++eet_initcount;
}
int bytes_directory_entries;
int num_dictionary_entries;
int bytes_dictionary_entries;
+ int signature_base_offset;
int i;
index += sizeof(int);
if (eet_test_close(!ef->header->directory->nodes, ef))
return NULL;
+ signature_base_offset = 0;
+
/* actually read the directory block - all of it, into ram */
for (i = 0; i < num_directory_entries; ++i)
{
if (efn->data)
memcpy(efn->data, ef->data + efn->offset, efn->size);
}
+
+ /* compute the possible position of a signature */
+ if (signature_base_offset < efn->offset + efn->size)
+ signature_base_offset = efn->offset + efn->size;
}
ef->ed = NULL;
ef->ed->all[j].hash = hash;
if (ef->ed->all[j].prev == -1)
ef->ed->hash[hash] = j;
+
+ /* compute the possible position of a signature */
+ if (signature_base_offset < offset + ef->ed->all[j].len)
+ signature_base_offset = offset + ef->ed->all[j].len;
}
}
+ /* Check if the file is signed */
+ ef->x509_der = NULL;
+ ef->x509_length = 0;
+ if (signature_base_offset < ef->data_size)
+ {
+#ifdef HAVE_SIGNATURE
+ const unsigned char *buffer = ((const unsigned char*) ef->data) + signature_base_offset;
+ ef->x509_der = eet_identity_check(ef->data, signature_base_offset,
+ buffer, ef->data_size - signature_base_offset,
+ &ef->x509_length);
+
+ if (ef->x509_der == NULL)
+ {
+ ef->delete_me_now = 1;
+ eet_close(ef);
+ return NULL;
+ }
+#else
+ fprintf(stderr, "This file could be signed but you didn't compile the necessary code to check the signature.\n");
+#endif
+ }
+
return ef;
}
ef->ed = NULL;
ef->path = NULL;
+ ef->key = NULL;
ef->magic = EET_MAGIC_FILE;
ef->references = 1;
ef->mode = EET_FILE_MODE_READ;
/* fill some of the members */
ef->fp = fp;
+ ef->key = NULL;
ef->readfp = NULL;
ef->path = ((char *)ef) + sizeof(Eet_File);
memcpy(ef->path, file, file_len);
return ef->mode;
}
+EAPI const void *
+eet_identity_x509(Eet_File *ef, int *der_length)
+{
+ if (!ef->x509_der) return NULL;
+
+ if (der_length) *der_length = ef->x509_length;
+ return ef->x509_der;
+}
+
+EAPI Eet_Error
+eet_identity_set(Eet_File *ef, Eet_Key *key)
+{
+ Eet_Key *tmp = ef->key;
+
+ if (!ef) return EET_ERROR_BAD_OBJECT;
+
+ ef->key = key;
+ eet_identity_ref(ef->key);
+ eet_identity_unref(tmp);
+
+ /* flags that writes are pending */
+ ef->writes_pending = 1;
+
+ return EET_ERROR_NONE;
+}
+
EAPI Eet_Error
eet_close(Eet_File *ef)
{
/* flush any writes */
err = eet_flush2(ef);
+ eet_identity_unref(ef->key);
+ ef->key = NULL;
+
/* if not urgent to delete it - dont free it - leave it in cache */
if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ))
return EET_ERROR_NONE;
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDmTCCAwKgAwIBAgIJAIKWPcLUT5FAMA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD
+VQQGEwJGUjEWMBQGA1UECBMNSWxlLURlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMx
+FjAUBgNVBAoTDUVubGlnaHRlbm1lbnQxDjAMBgNVBAsTBVRlc3RzMQ0wCwYDVQQD
+EwRCQUlMMSIwIAYJKoZIhvcNAQkBFhNjZWRyaWMuYmFpbEBmcmVlLmZyMB4XDTA4
+MDczMDEzNDU1OVoXDTA5MDczMDEzNDU1OVowgZAxCzAJBgNVBAYTAkZSMRYwFAYD
+VQQIEw1JbGUtRGUtRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczEWMBQGA1UEChMNRW5s
+aWdodGVubWVudDEOMAwGA1UECxMFVGVzdHMxDTALBgNVBAMTBEJBSUwxIjAgBgkq
+hkiG9w0BCQEWE2NlZHJpYy5iYWlsQGZyZWUuZnIwgZ8wDQYJKoZIhvcNAQEBBQAD
+gY0AMIGJAoGBAMiE486eROKePG0/639D4XTTDR9XSRWp1xqZzq7P+jjWRFbZ/MWV
+IVzkc4MRm83UOolbPj76LjM10cseaVAhK7G9CHp2dur4alWvdCXPH5Q+LPOFS9gM
+x0Jz9EZeHHOHZKLyJdKSmot+zluwJTLe081RRUwzNKct6JrVVG/7SmITAgMBAAGj
+gfgwgfUwHQYDVR0OBBYEFEFar6doT5ImL2rf0rJX7EYQqtYQMIHFBgNVHSMEgb0w
+gbqAFEFar6doT5ImL2rf0rJX7EYQqtYQoYGWpIGTMIGQMQswCQYDVQQGEwJGUjEW
+MBQGA1UECBMNSWxlLURlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxFjAUBgNVBAoT
+DUVubGlnaHRlbm1lbnQxDjAMBgNVBAsTBVRlc3RzMQ0wCwYDVQQDEwRCQUlMMSIw
+IAYJKoZIhvcNAQkBFhNjZWRyaWMuYmFpbEBmcmVlLmZyggkAgpY9wtRPkUAwDAYD
+VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCpZJhk8BgQh0foiMkOwOMKvObq
+GxAzqjbr7iU9tEvJgwukCBv59ndBM0B5l5ybQdIYWQJOfZE1HTvB60swZMwqap9X
+5QXgewymuXiVk+roVh34wg8Pg8F588G2BtLIoujY/gN3WJQR7YPD34iTPc4koV+A
+4vs6nmL6wtW21+hsaw==
+-----END CERTIFICATE-----
+#include <sys/types.h>
+#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
+#include <fcntl.h>
#include <check.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include "eet_suite.h"
START_TEST(eet_test_init)
}
END_TEST
+START_TEST(eet_identity_simple)
+{
+ const char *buffer = "Here is a string of data to save !";
+ const void *tmp;
+ Eet_File *ef;
+ Eet_Key *k;
+ char *test;
+ char *file = strdup("/tmp/eet_suite_testXXXXXX");
+ int size;
+ int fd;
+
+ eet_init();
+
+ mktemp(file);
+ chdir("src/tests");
+
+ /* Sign an eet file. */
+ ef = eet_open(file, EET_FILE_MODE_WRITE);
+ fail_if(!ef);
+
+ fail_if(!eet_write(ef, "keys/tests", buffer, strlen(buffer) + 1, 0));
+
+ k = eet_identity_open("cert.pem", "key.pem", NULL);
+ fail_if(!k);
+
+ fail_if(eet_identity_set(ef, k) != EET_ERROR_NONE);
+
+ eet_close(ef);
+
+ /* Open a signed file. */
+ ef = eet_open(file, EET_FILE_MODE_READ);
+ fail_if(!ef);
+
+ test = eet_read(ef, "keys/tests", &size);
+ fail_if(!test);
+ fail_if(size != strlen(buffer) + 1);
+
+ fail_if(memcmp(test, buffer, strlen(buffer) + 1) != 0);
+
+ tmp = eet_identity_x509(ef, &size);
+ fail_if(tmp == NULL);
+
+ eet_close(ef);
+
+ /* As we are changing file contain in less than 1s, this could get unnoticed
+ by eet cache system. */
+ eet_clearcache();
+
+ /* Corrupting the file. */
+ fd = open(file, O_WRONLY);
+ fail_if(fd < 0);
+
+ fail_if(lseek(fd, 200, SEEK_SET) != 200);
+ fail_if(write(fd, "42", 2) != 2);
+ fail_if(lseek(fd, 50, SEEK_SET) != 50);
+ fail_if(write(fd, "42", 2) != 2);
+ fail_if(lseek(fd, 88, SEEK_SET) != 88);
+ fail_if(write(fd, "42", 2) != 2);
+
+ close(fd);
+
+ /* Attempt to open a modified file. */
+ ef = eet_open(file, EET_FILE_MODE_READ);
+ fail_if(ef);
+
+ fail_if(unlink(file) != 0);
+
+ eet_shutdown();
+}
+END_TEST
+
Suite *
eet_suite(void)
{
tcase_add_test(tc, eet_small_image);
suite_add_tcase(s, tc);
+#ifdef HAVE_SIGNATURE
+ tc = tcase_create("Eet Identity");
+ tcase_add_test(tc, eet_identity_simple);
+ suite_add_tcase(s, tc);
+#endif
+
return s;
}
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDIhOPOnkTinjxtP+t/Q+F00w0fV0kVqdcamc6uz/o41kRW2fzF
+lSFc5HODEZvN1DqJWz4++i4zNdHLHmlQISuxvQh6dnbq+GpVr3Qlzx+UPizzhUvY
+DMdCc/RGXhxzh2Si8iXSkpqLfs5bsCUy3tPNUUVMMzSnLeia1VRv+0piEwIDAQAB
+AoGAfLLHyNJ8HEIzae16UmawaqplWrw5YxOABbbo5aXJAledoDVoEKexW8dmXngw
+4Eu/K3RmvVtwJ8CsexiqfX5jYMU+YKRbww6Vqr/punIUhiEHVarHMFKG9yo14qSa
+z2xPgXvC5p7/Rhci+rAUp36S5kIHch5sLhEEcJayymyzDyECQQD/5B3JdpcovrSI
++nyZ8Iub2+I3f3uox6m1DKxHead26ICoIr7VCnPV5J1gLIB2MofVCbKhmy4PNi5a
+0QdvazJfAkEAyJq9Y+9SQ4sCOVDrFklJxhXuZE4WbnR32XsBdnQ9dauo0E2vDVkv
+6mHnzMWroTjLv4hH5nufE5NvMo8PNGB0zQJAFOKkf737JmsyRv/Szamxa14t/4Ob
+LzJkqo9HPGo0feMKJS74zmCVBb8sDR50ubD0HzI0bzZAMyOj8uuepLxmFwJAH+RR
+5bhfeLN52AjgRvvBycckzjeH42mKwD2I/v794l43CV7ATLv4HSgRhQGMBqaT5dBR
+tffDU4Zl8EDEJwyKpQJBAJ2NNacURTyavU699QJOIdGAsA4KXici8H3PuuWMtHLR
+RKdPFeaCRn+9p7Tglf0rH9hUGOpUXHYD3+ECt6gnVDc=
+-----END RSA PRIVATE KEY-----