Add signature support in eet.

You can use eet -s to sign a eet file and eet -c to check its signature. The
current code doesn't check any certificate trust path, only if the signature
match the certificate and that the certificate could be loaded. If that's not
the case, eet_open will fail. If the file is not signed, eet_open will just
continue to succeed.



SVN revision: 35882
This commit is contained in:
Cedric BAIL 2008-09-08 09:19:57 +00:00
parent aa2fded0fc
commit 46b7796946
10 changed files with 760 additions and 4 deletions

View File

@ -143,6 +143,54 @@ fi
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,
@ -241,6 +289,10 @@ echo "------------------------------------------------------------------------"
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

View File

@ -200,6 +200,50 @@ do_eet_remove(const char *file, const char *key)
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)
{
@ -214,6 +258,8 @@ 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;
@ -250,6 +296,18 @@ main(int argc, char **argv)
{
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;
}

View File

@ -2,6 +2,7 @@
#define _EET_H
#include <stdlib.h>
#include <stdio.h>
#ifdef EAPI
# undef EAPI
@ -86,12 +87,19 @@ extern "C" {
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;
@ -247,6 +255,60 @@ extern "C" {
*/
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

View File

@ -12,6 +12,14 @@
# 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
@ -53,6 +61,15 @@ struct _Eet_Dictionary
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);
@ -66,6 +83,15 @@ int _eet_hash_gen(const char *key, int hash_size);
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

View File

@ -8,7 +8,8 @@ AM_CPPFLAGS = \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EVIL_CFLAGS@ \
@COVERAGE_CFLAGS@
@COVERAGE_CFLAGS@ \
@OPENSSL_CFLAGS@
include_HEADERS = Eet.h
@ -18,6 +19,7 @@ libeet_la_SOURCES = \
eet_lib.c \
eet_data.c \
eet_image.c \
eet_cypher.c \
eet_dictionary.c \
eet_utils.c

View File

@ -0,0 +1,335 @@
#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
}

View File

@ -69,14 +69,17 @@ struct _Eet_File
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;
@ -158,6 +161,11 @@ struct
} 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
@ -379,8 +387,11 @@ eet_flush2(Eet_File *ef)
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);
}
@ -516,6 +527,17 @@ eet_flush2(Eet_File *ef)
}
}
/* 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;
@ -651,6 +673,7 @@ eet_flush(Eet_File *ef)
ef->fp = NULL;
return EET_ERROR_WRITE_ERROR;
}
sign_error:
fclose(ef->fp);
ef->fp = NULL;
return EET_ERROR_WRITE_ERROR;
@ -660,6 +683,19 @@ eet_flush(Eet_File *ef)
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;
}
@ -738,6 +774,7 @@ eet_internal_read2(Eet_File *ef)
int bytes_directory_entries;
int num_dictionary_entries;
int bytes_dictionary_entries;
int signature_base_offset;
int i;
index += sizeof(int);
@ -787,6 +824,8 @@ eet_internal_read2(Eet_File *ef)
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)
{
@ -850,6 +889,10 @@ eet_internal_read2(Eet_File *ef)
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;
@ -906,9 +949,35 @@ eet_internal_read2(Eet_File *ef)
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;
}
@ -1120,6 +1189,7 @@ eet_memopen_read(const void *data, size_t size)
ef->ed = NULL;
ef->path = NULL;
ef->key = NULL;
ef->magic = EET_MAGIC_FILE;
ef->references = 1;
ef->mode = EET_FILE_MODE_READ;
@ -1229,6 +1299,7 @@ eet_open(const char *file, Eet_File_Mode mode)
/* 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);
@ -1297,6 +1368,32 @@ eet_mode_get(Eet_File *ef)
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)
{
@ -1312,6 +1409,9 @@ 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;

View File

@ -0,0 +1,22 @@
-----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-----

View File

@ -1,10 +1,17 @@
#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)
@ -1146,6 +1153,77 @@ START_TEST(eet_small_image)
}
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)
{
@ -1175,6 +1253,12 @@ 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;
}

View File

@ -0,0 +1,15 @@
-----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-----