summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--legacy/eet/configure.in52
-rw-r--r--legacy/eet/src/bin/eet_main.c58
-rw-r--r--legacy/eet/src/lib/Eet.h64
-rw-r--r--legacy/eet/src/lib/Eet_private.h26
-rw-r--r--legacy/eet/src/lib/Makefile.am4
-rw-r--r--legacy/eet/src/lib/eet_cypher.c335
-rw-r--r--legacy/eet/src/lib/eet_lib.c104
-rw-r--r--legacy/eet/src/tests/cert.pem22
-rw-r--r--legacy/eet/src/tests/eet_suite.c84
-rw-r--r--legacy/eet/src/tests/key.pem15
10 files changed, 760 insertions, 4 deletions
diff --git a/legacy/eet/configure.in b/legacy/eet/configure.in
index ebf301e28b..21026ee0be 100644
--- a/legacy/eet/configure.in
+++ b/legacy/eet/configure.in
@@ -143,6 +143,54 @@ fi
143 143
144AM_CONDITIONAL(EET_ENABLE_TESTS, test "x${enable_tests}" = "xyes") 144AM_CONDITIONAL(EET_ENABLE_TESTS, test "x${enable_tests}" = "xyes")
145 145
146dnl Openssl support
147want_openssl="auto"
148have_openssl="no"
149AC_ARG_ENABLE(openssl,
150 [AC_HELP_STRING([--disable-openssl], [disable openssl eet support])],
151 [ want_openssl=$enableval ]
152)
153if test "x$want_openssl" = "xyes" -o "x$want_openssl" = "xauto"; then
154 PKG_CHECK_MODULES(OPENSSL, openssl,
155 [
156 have_openssl="yes"
157 AC_DEFINE(HAVE_OPENSSL, 1, [Have Openssl support])
158 ],
159 [
160 if test "x$use_strict" = "xyes"; then
161 AC_MSG_ERROR([Openssl not found (strict dependencies checking)])
162 fi
163 ])
164fi
165
166dnl Crypto option
167want_cypher="yes"
168have_cypher="no"
169want_signature="yes"
170have_signature="no"
171
172AC_MSG_CHECKING(whether to activate cypher support in eet)
173AC_ARG_ENABLE(cypher,
174 [AC_HELP_STRING([--disable-cypher], [disable cypher support for eet API])],
175 [ want_cypher=$enableval ]
176)
177if test "x$have_openssl" = "xyes" -a "x$want_cypher" = "xyes"; then
178 have_cypher="yes"
179 AC_DEFINE(HAVE_CYPHER, 1, [Have cypher support built in eet])
180fi
181AC_MSG_RESULT($have_cypher)
182
183AC_MSG_CHECKING(whether to activate signature support in eet)
184AC_ARG_ENABLE(signature,
185 [AC_HELP_STRING([--disable-signature], [disable signature file support for eet])],
186 [ want_signature=$enableval ]
187)
188if test "x$have_openssl" = "xyes" -a "x$want_signature" = "xyes"; then
189 have_signature="yes"
190 AC_DEFINE(HAVE_SIGNATURE, 1, [Have signature support for eet file])
191fi
192AC_MSG_RESULT($have_signature)
193
146dnl Coverage 194dnl Coverage
147 195
148AC_ARG_ENABLE(coverage, 196AC_ARG_ENABLE(coverage,
@@ -241,6 +289,10 @@ echo "------------------------------------------------------------------------"
241echo 289echo
242echo "Configuration Options Summary:" 290echo "Configuration Options Summary:"
243echo 291echo
292echo " Openssl..............: ${have_openssl}"
293echo " Cypher support.....: ${have_cypher}"
294echo " Signature..........: ${have_signature}"
295
244echo " Tests................: ${enable_tests}" 296echo " Tests................: ${enable_tests}"
245echo " Coverage.............: ${enable_coverage}" 297echo " Coverage.............: ${enable_coverage}"
246echo 298echo
diff --git a/legacy/eet/src/bin/eet_main.c b/legacy/eet/src/bin/eet_main.c
index 539cec8854..0db402641a 100644
--- a/legacy/eet/src/bin/eet_main.c
+++ b/legacy/eet/src/bin/eet_main.c
@@ -200,6 +200,50 @@ do_eet_remove(const char *file, const char *key)
200 eet_close(ef); 200 eet_close(ef);
201} 201}
202 202
203static void
204do_eet_check(const char *file)
205{
206 Eet_File *ef;
207 const void *der;
208 int der_length;
209
210 ef = eet_open(file, EET_FILE_MODE_READ);
211 if (!ef)
212 {
213 fprintf(stdout, "checking signature of `%s` failed\n", file);
214 exit(-1);
215 }
216
217 der = eet_identity_x509(ef, &der_length);
218
219 eet_identity_certificate_print(der, der_length, stdout);
220
221 eet_close(ef);
222}
223
224static void
225do_eet_sign(const char *file, const char *private_key, const char *public_key)
226{
227 Eet_File *ef;
228 Eet_Key *key;
229
230 ef = eet_open(file, EET_FILE_MODE_READ_WRITE);
231 if (!ef)
232 {
233 fprintf(stdout, "cannot open for read+write: %s.\n", file);
234 exit(-1);
235 }
236
237 key = eet_identity_open(public_key, private_key, NULL);
238
239 fprintf(stdout, "Using the following key to sign `%s`.\n", file);
240 eet_identity_print(key, stdout);
241
242 eet_identity_set(ef, key);
243
244 eet_close(ef);
245}
246
203int 247int
204main(int argc, char **argv) 248main(int argc, char **argv)
205{ 249{
@@ -214,6 +258,8 @@ main(int argc, char **argv)
214 " 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" 258 " 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"
215 " 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" 259 " 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"
216 " eet -r FILE.EET KEY remove KEY in FILE.EET\n" 260 " eet -r FILE.EET KEY remove KEY in FILE.EET\n"
261 " eet -c FILE.EET report and check the signature information of an eet file\n"
262 " eet -s FILE.EET PRIVATE_KEY PUBLIC_KEY sign FILE.EET with PRIVATE_KEY and attach PUBLIC_KEY as it's certificate\n"
217 ); 263 );
218 eet_shutdown(); 264 eet_shutdown();
219 return -1; 265 return -1;
@@ -250,6 +296,18 @@ main(int argc, char **argv)
250 { 296 {
251 goto help; 297 goto help;
252 } 298 }
299 else if ((!strcmp(argv[1], "-c")) && (argc > 2))
300 {
301 do_eet_check(argv[2]);
302 }
303 else if ((!strcmp(argv[1], "-s")) && (argc > 4))
304 {
305 do_eet_sign(argv[2], argv[3], argv[4]);
306 }
307 else
308 {
309 goto help;
310 }
253 eet_shutdown(); 311 eet_shutdown();
254 return 0; 312 return 0;
255} 313}
diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h
index 2f52aab8b6..c528bc2e8e 100644
--- a/legacy/eet/src/lib/Eet.h
+++ b/legacy/eet/src/lib/Eet.h
@@ -2,6 +2,7 @@
2#define _EET_H 2#define _EET_H
3 3
4#include <stdlib.h> 4#include <stdlib.h>
5#include <stdio.h>
5 6
6#ifdef EAPI 7#ifdef EAPI
7# undef EAPI 8# undef EAPI
@@ -86,12 +87,19 @@ extern "C" {
86 EET_ERROR_WRITE_ERROR_FILE_TOO_BIG, 87 EET_ERROR_WRITE_ERROR_FILE_TOO_BIG,
87 EET_ERROR_WRITE_ERROR_IO_ERROR, 88 EET_ERROR_WRITE_ERROR_IO_ERROR,
88 EET_ERROR_WRITE_ERROR_OUT_OF_SPACE, 89 EET_ERROR_WRITE_ERROR_OUT_OF_SPACE,
89 EET_ERROR_WRITE_ERROR_FILE_CLOSED 90 EET_ERROR_WRITE_ERROR_FILE_CLOSED,
91 EET_ERROR_MMAP_FAILED,
92 EET_ERROR_X509_ENCODING_FAILED,
93 EET_ERROR_SIGNATURE_FAILED,
94 EET_ERROR_INVALID_SIGNATURE,
95 EET_ERROR_NOT_SIGNED,
96 EET_ERROR_NOT_IMPLEMENTED
90 } Eet_Error; 97 } Eet_Error;
91 98
92 typedef struct _Eet_File Eet_File; 99 typedef struct _Eet_File Eet_File;
93 typedef struct _Eet_Dictionary Eet_Dictionary; 100 typedef struct _Eet_Dictionary Eet_Dictionary;
94 typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor; 101 typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor;
102 typedef struct _Eet_Key Eet_Key;
95 103
96 typedef struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class; 104 typedef struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class;
97 105
@@ -247,6 +255,60 @@ extern "C" {
247 */ 255 */
248 EAPI Eet_Error eet_close(Eet_File *ef); 256 EAPI Eet_Error eet_close(Eet_File *ef);
249 257
258 /**
259 * Callback used to request if needed the password of a private key.
260 *
261 * @since 2.0.0
262 */
263 typedef int (*Eet_Key_Password_Callback)(char *buffer, int size, int rwflag, void *data);
264
265 /**
266 * Create an Eet_Key needed for signing an eet file.
267 *
268 * The certificate should provide the public that match the private key.
269 * No verification is done to ensure that.
270 *
271 * @since 2.0.0
272 */
273 EAPI Eet_Key* eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb);
274
275 /**
276 * Close and release all ressource used by an Eet_Key.
277 * An reference counter prevent it from being freed until all file using it are
278 * also closed.
279 *
280 * @since 2.0.0
281 */
282 EAPI void eet_identity_close(Eet_Key *key);
283
284 /**
285 * Set a key to sign a file
286 *
287 * @since 2.0.0
288 */
289 EAPI Eet_Error eet_identity_set(Eet_File *ef, Eet_Key *key);
290
291 /**
292 * Display both private and public key of an Eet_Key.
293 *
294 * @since 2.0.0
295 */
296 EAPI void eet_identity_print(Eet_Key *key, FILE *out);
297
298 /**
299 * Get the x509 der certificate associated with an Eet_File. Will return NULL
300 * if the file is not signed.
301 *
302 * @since 2.0.0
303 */
304 EAPI const void *eet_identity_x509(Eet_File *ef, int *der_length);
305
306 /**
307 * Display the x509 der certificate to out.
308 *
309 * @since 2.0.0
310 */
311 EAPI void eet_identity_certificate_print(const unsigned char *certificate, int der_length, FILE *out);
250 312
251 /** 313 /**
252 * Return a handle to the shared string dictionary of the Eet file 314 * Return a handle to the shared string dictionary of the Eet file
diff --git a/legacy/eet/src/lib/Eet_private.h b/legacy/eet/src/lib/Eet_private.h
index 7160783e98..57da2a4744 100644
--- a/legacy/eet/src/lib/Eet_private.h
+++ b/legacy/eet/src/lib/Eet_private.h
@@ -12,6 +12,14 @@
12# endif 12# endif
13#endif 13#endif
14 14
15#include "config.h"
16
17#ifdef HAVE_OPENSSL
18#include <openssl/evp.h>
19#include <openssl/x509.h>
20#include <openssl/pem.h>
21#endif
22
15typedef struct _Eet_String Eet_String; 23typedef struct _Eet_String Eet_String;
16 24
17struct _Eet_String 25struct _Eet_String
@@ -53,6 +61,15 @@ struct _Eet_Dictionary
53 const char *end; 61 const char *end;
54}; 62};
55 63
64struct _Eet_Key
65{
66 int references;
67#ifdef HAVE_SIGNATURE
68 X509 *certificate;
69 EVP_PKEY *private_key;
70#endif
71};
72
56Eet_Dictionary *eet_dictionary_add(void); 73Eet_Dictionary *eet_dictionary_add(void);
57void eet_dictionary_free(Eet_Dictionary *ed); 74void eet_dictionary_free(Eet_Dictionary *ed);
58int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string); 75int eet_dictionary_string_add(Eet_Dictionary *ed, const char *string);
@@ -66,6 +83,15 @@ int _eet_hash_gen(const char *key, int hash_size);
66int _eet_string_to_double_convert(const char *src, long long *m, long *e); 83int _eet_string_to_double_convert(const char *src, long long *m, long *e);
67void _eet_double_to_string_convert(char des[128], double d); 84void _eet_double_to_string_convert(char des[128], double d);
68 85
86const void* eet_identity_check(const void *data_base, unsigned int data_length,
87 const void *signature_base, unsigned int signature_length,
88 int *x509_length);
89Eet_Error eet_cypher(void *data, unsigned int size, const char *key, unsigned int length);
90Eet_Error eet_decypher(void *data, unsigned int size, const char *key, unsigned int length);
91Eet_Error eet_identity_sign(FILE *fp, Eet_Key *key);
92void eet_identity_unref(Eet_Key *key);
93void eet_identity_ref(Eet_Key *key);
94
69#ifndef PATH_MAX 95#ifndef PATH_MAX
70#define PATH_MAX 4096 96#define PATH_MAX 4096
71#endif 97#endif
diff --git a/legacy/eet/src/lib/Makefile.am b/legacy/eet/src/lib/Makefile.am
index 0214fa3e77..7055ffd7a2 100644
--- a/legacy/eet/src/lib/Makefile.am
+++ b/legacy/eet/src/lib/Makefile.am
@@ -8,7 +8,8 @@ AM_CPPFLAGS = \
8-DPACKAGE_LIB_DIR=\"$(libdir)\" \ 8-DPACKAGE_LIB_DIR=\"$(libdir)\" \
9-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \ 9-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
10@EVIL_CFLAGS@ \ 10@EVIL_CFLAGS@ \
11@COVERAGE_CFLAGS@ 11@COVERAGE_CFLAGS@ \
12@OPENSSL_CFLAGS@
12 13
13include_HEADERS = Eet.h 14include_HEADERS = Eet.h
14 15
@@ -18,6 +19,7 @@ libeet_la_SOURCES = \
18eet_lib.c \ 19eet_lib.c \
19eet_data.c \ 20eet_data.c \
20eet_image.c \ 21eet_image.c \
22eet_cypher.c \
21eet_dictionary.c \ 23eet_dictionary.c \
22eet_utils.c 24eet_utils.c
23 25
diff --git a/legacy/eet/src/lib/eet_cypher.c b/legacy/eet/src/lib/eet_cypher.c
new file mode 100644
index 0000000000..dcaab55357
--- /dev/null
+++ b/legacy/eet/src/lib/eet_cypher.c
@@ -0,0 +1,335 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdio.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <unistd.h>
9#include <sys/mman.h>
10
11#ifdef HAVE_SIGNATURE
12# include <openssl/rsa.h>
13# include <openssl/objects.h>
14# include <openssl/err.h>
15# include <openssl/ssl.h>
16# include <openssl/dh.h>
17# include <openssl/dsa.h>
18#endif
19
20#include "Eet.h"
21#include "Eet_private.h"
22
23#define EET_MAGIC_SIGN 0x1ee74271
24
25EAPI Eet_Key*
26eet_identity_open(const char *certificate_file, const char *private_key_file, Eet_Key_Password_Callback cb)
27{
28#ifdef HAVE_SIGNATURE
29 EVP_PKEY *pkey = NULL;
30 X509 *cert = NULL;
31 Eet_Key *key;
32 FILE *fp;
33
34 /* Load the X509 certificate in memory. */
35 fp = fopen(certificate_file, "r");
36 if (!fp) return NULL;
37 cert = PEM_read_X509(fp, NULL, NULL, NULL);
38 fclose(fp);
39 if (!cert) return NULL;
40
41 /* Check the presence of the public key. Just in case. */
42 pkey = X509_get_pubkey(cert);
43 if (!pkey) goto on_error;
44
45 /* Load the private key in memory. */
46 fp = fopen(private_key_file, "r");
47 if (!fp) goto on_error;
48 pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
49 fclose(fp);
50 if (!pkey) goto on_error;
51
52 key = malloc(sizeof(Eet_Key));
53 if (!key) goto on_error;
54
55 key->references = 1;
56 key->certificate = cert;
57 key->private_key = pkey;
58
59 return key;
60
61 on_error:
62 if (cert) X509_free(cert);
63 if (pkey) EVP_PKEY_free(pkey);
64#endif
65 return NULL;
66}
67
68EAPI void
69eet_identity_print(Eet_Key *key, FILE *out)
70{
71#ifdef HAVE_SIGNATURE
72 RSA *rsa;
73 DSA *dsa;
74 DH *dh;
75
76 if (!key) return ;
77
78 rsa = EVP_PKEY_get1_RSA(key->private_key);
79 if (rsa)
80 {
81 fprintf(out, "Private key (RSA) :\n");
82 RSA_print_fp(out, rsa, 0);
83 }
84
85 dsa = EVP_PKEY_get1_DSA(key->private_key);
86 if (dsa)
87 {
88 fprintf(out, "Private key (DSA) :\n");
89 DSA_print_fp(out, dsa, 0);
90 }
91
92 dh = EVP_PKEY_get1_DH(key->private_key);
93 if (dh)
94 {
95 fprintf(out, "Private key (DH) :\n");
96 DHparams_print_fp(out, dh);
97 }
98
99 fprintf(out, "Public certificate :\n");
100 X509_print_fp(out, key->certificate);
101#else
102 fprintf(out, "You need to compile signature support in EET.\n");
103#endif
104}
105
106EAPI void
107eet_identity_close(Eet_Key *key)
108{
109#ifdef HAVE_SIGNATURE
110 if (key->references > 0) return ;
111
112 X509_free(key->certificate);
113 EVP_PKEY_free(key->private_key);
114 free(key);
115#endif
116}
117
118void
119eet_identity_ref(Eet_Key *key)
120{
121 if (key == NULL) return ;
122 key->references++;
123}
124
125void
126eet_identity_unref(Eet_Key *key)
127{
128 if (key == NULL) return ;
129 key->references--;
130 eet_identity_close(key);
131}
132
133Eet_Error
134eet_identity_sign(FILE *fp, Eet_Key *key)
135{
136#ifdef HAVE_SIGNATURE
137 unsigned char *x509_der = NULL;
138 void *sign = NULL;
139 void *data;
140 int head[3];
141 EVP_MD_CTX md_ctx;
142 struct stat st_buf;
143 Eet_Error err = EET_ERROR_NONE;
144 int sign_length;
145 int x509_length;
146 int fd;
147
148 /* A few check and flush pending write. */
149 if (!fp
150 || !key
151 || !key->certificate
152 || !key->private_key)
153 return EET_ERROR_BAD_OBJECT;
154
155 /* Get the file size. */
156 fd = fileno(fp);
157 if (fd < 0) return EET_ERROR_BAD_OBJECT;
158 if (fstat(fd, &st_buf) < 0) return EET_ERROR_MMAP_FAILED;
159
160 /* Map the file in memory. */
161 data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
162 if (data == MAP_FAILED) return EET_ERROR_MMAP_FAILED;
163
164 sign_length = EVP_PKEY_size(key->private_key);
165 sign = malloc(sign_length);
166 if (sign == NULL)
167 {
168 err = EET_ERROR_OUT_OF_MEMORY;
169 goto on_error;
170 }
171
172 /* Do the signature. */
173 EVP_SignInit(&md_ctx, EVP_sha1());
174 EVP_SignUpdate (&md_ctx, data, st_buf.st_size);
175 err = EVP_SignFinal (&md_ctx, sign, &sign_length, key->private_key);
176 if (err != 1)
177 {
178 ERR_print_errors_fp(stdout);
179 err = EET_ERROR_SIGNATURE_FAILED;
180 goto on_error;
181 }
182
183 /* Give me the der (binary form for X509). */
184 x509_length = i2d_X509(key->certificate, &x509_der);
185 if (x509_length < 0)
186 {
187 ERR_print_errors_fp(stdout);
188 err = EET_ERROR_X509_ENCODING_FAILED;
189 goto on_error;
190 }
191
192 /* Append the signature at the end of the file. */
193 head[0] = (int) htonl ((unsigned int) EET_MAGIC_SIGN);
194 head[1] = (int) htonl ((unsigned int) sign_length);
195 head[2] = (int) htonl ((unsigned int) x509_length);
196
197 if (fwrite(head, sizeof(head), 1, fp) != 1)
198 {
199 err = EET_ERROR_WRITE_ERROR;
200 goto on_error;
201 }
202 if (fwrite(sign, sign_length, 1, fp) != 1)
203 {
204 err = EET_ERROR_WRITE_ERROR;
205 goto on_error;
206 }
207 if (fwrite(x509_der, x509_length, 1, fp) != 1)
208 {
209 err = EET_ERROR_WRITE_ERROR;
210 goto on_error;
211 }
212
213 on_error:
214 if (x509_der) OPENSSL_free(x509_der);
215 if (sign != NULL) free(sign);
216 munmap(data, st_buf.st_size);
217 return err;
218#else
219 return EET_ERROR_NOT_IMPLEMENTED;
220#endif
221}
222
223const void*
224eet_identity_check(const void *data_base, unsigned int data_length,
225 const void *signature_base, unsigned int signature_length,
226 int *x509_length)
227{
228#ifdef HAVE_SIGNATURE
229 const int *header = signature_base;
230 const unsigned char *sign;
231 const unsigned char *cert_der;
232 const unsigned char *tmp;
233 EVP_PKEY *pkey;
234 X509 *x509;
235 EVP_MD_CTX md_ctx;
236 int sign_length;
237 int cert_length;
238 int magic;
239 int err;
240
241 if (signature_length < sizeof(int) * 3) return NULL;
242
243 magic = ntohl(header[0]);
244 sign_length = ntohl(header[1]);
245 cert_length = ntohl(header[2]);
246
247 if (magic != EET_MAGIC_SIGN) return NULL;
248 if (sign_length + cert_length + sizeof(int) * 3 > signature_length) return NULL;
249
250 sign = signature_base + sizeof(int) * 3;
251 cert_der = sign + sign_length;
252
253 /* Strange but d2i_X509 seems to put 0 all over the place. */
254 tmp = alloca(cert_length);
255 memcpy((char*) tmp, cert_der, cert_length);
256 x509 = d2i_X509(NULL, &tmp, cert_length);
257 if (x509 == NULL) return NULL;
258
259 /* Get public key - eay */
260 pkey=X509_get_pubkey(x509);
261 if (pkey == NULL)
262 {
263 X509_free(x509);
264 return NULL;
265 }
266
267 /* Verify the signature */
268 EVP_VerifyInit(&md_ctx, EVP_sha1());
269 EVP_VerifyUpdate(&md_ctx, data_base, data_length);
270 err = EVP_VerifyFinal(&md_ctx, sign, sign_length, pkey);
271
272 X509_free(x509);
273 EVP_PKEY_free(pkey);
274
275 if (err != 1)
276 return NULL;
277
278 if (x509_length) *x509_length = cert_length;
279 return cert_der;
280#else
281 return NULL;
282#endif
283}
284
285EAPI void
286eet_identity_certificate_print(const unsigned char *certificate, int der_length, FILE *out)
287{
288#ifdef HAVE_SIGNATURE
289 const unsigned char *tmp;
290 X509 *x509;
291
292 if (certificate == NULL
293 || out == NULL
294 || der_length <= 0)
295 {
296 fprintf(out, "No certificate provided.\n");
297 return ;
298 }
299
300 /* Strange but d2i_X509 seems to put 0 all over the place. */
301 tmp = alloca(der_length);
302 memcpy((char*) tmp, certificate, der_length);
303 x509 = d2i_X509(NULL, &tmp, der_length);
304 if (x509 == NULL)
305 {
306 fprintf(out, "Not a valid certificate.\n");
307 return ;
308 }
309
310 fprintf(out, "Public certificate :\n");
311 X509_print_fp(out, x509);
312
313 X509_free(x509);
314#else
315 fprintf(out, "You need to compile signature support in EET.\n");
316#endif
317}
318
319Eet_Error
320eet_cypher(void *data, unsigned int size, const char *key, unsigned int length)
321{
322#ifdef HAVE_CYPHER
323#else
324 return EET_ERROR_NOT_IMPLEMENTED;
325#endif
326}
327
328Eet_Error
329eet_decypher(void *data, unsigned int size, const char *key, unsigned int length)
330{
331#ifdef HAVE_CYPHER
332#else
333 return EET_ERROR_NOT_IMPLEMENTED;
334#endif
335}
diff --git a/legacy/eet/src/lib/eet_lib.c b/legacy/eet/src/lib/eet_lib.c
index 9d0be1ce38..76e60dfce1 100644
--- a/legacy/eet/src/lib/eet_lib.c
+++ b/legacy/eet/src/lib/eet_lib.c
@@ -69,14 +69,17 @@ struct _Eet_File
69 FILE *fp; 69 FILE *fp;
70 FILE *readfp; 70 FILE *readfp;
71 Eet_File_Header *header; 71 Eet_File_Header *header;
72 const unsigned char *data;
73 Eet_Dictionary *ed; 72 Eet_Dictionary *ed;
73 Eet_Key *key;
74 const unsigned char *data;
75 const void *x509_der;
74 76
75 int magic; 77 int magic;
76 int references; 78 int references;
77 79
78 Eet_File_Mode mode; 80 Eet_File_Mode mode;
79 int data_size; 81 int data_size;
82 int x509_length;
80 time_t mtime; 83 time_t mtime;
81 84
82 unsigned char writes_pending : 1; 85 unsigned char writes_pending : 1;
@@ -158,6 +161,11 @@ struct
158} dictionary[num_dictionary_entries]; 161} dictionary[num_dictionary_entries];
159/* now start the string stream. */ 162/* now start the string stream. */
160/* and right after them the data stream. */ 163/* and right after them the data stream. */
164int magic_sign; /* Optional, only if the eet file is signed. */
165int signature_length; /* Signature length. */
166int x509_length; /* Public certificate that signed the file. */
167char signature[signature_length]; /* The signature. */
168char x509[x509_length]; /* The public certificate. */
161#endif 169#endif
162 170
163#define EET_FILE2_HEADER_COUNT 3 171#define EET_FILE2_HEADER_COUNT 3
@@ -379,8 +387,11 @@ eet_flush2(Eet_File *ef)
379 return EET_ERROR_NONE; 387 return EET_ERROR_NONE;
380 if (ef->mode == EET_FILE_MODE_READ_WRITE && ef->fp == NULL) 388 if (ef->mode == EET_FILE_MODE_READ_WRITE && ef->fp == NULL)
381 { 389 {
390 int fd;
391
382 unlink(ef->path); 392 unlink(ef->path);
383 ef->fp = fopen(ef->path, "wb"); 393 fd = open(file, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
394 ef->fp = fdopen(fd, "wb");
384 if (!ef->fp) return EET_ERROR_NOT_WRITABLE; 395 if (!ef->fp) return EET_ERROR_NOT_WRITABLE;
385 fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC); 396 fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC);
386 } 397 }
@@ -516,6 +527,17 @@ eet_flush2(Eet_File *ef)
516 } 527 }
517 } 528 }
518 529
530 /* flush all write to the file. */
531 fflush(ef->fp);
532
533 /* append signature if required */
534 if (ef->key)
535 {
536 error = eet_identity_sign(ef->fp, ef->key);
537 if (error != EET_ERROR_NONE)
538 goto sign_error;
539 }
540
519 /* no more writes pending */ 541 /* no more writes pending */
520 ef->writes_pending = 0; 542 ef->writes_pending = 0;
521 543
@@ -651,6 +673,7 @@ eet_flush(Eet_File *ef)
651 ef->fp = NULL; 673 ef->fp = NULL;
652 return EET_ERROR_WRITE_ERROR; 674 return EET_ERROR_WRITE_ERROR;
653 } 675 }
676 sign_error:
654 fclose(ef->fp); 677 fclose(ef->fp);
655 ef->fp = NULL; 678 ef->fp = NULL;
656 return EET_ERROR_WRITE_ERROR; 679 return EET_ERROR_WRITE_ERROR;
@@ -660,6 +683,19 @@ eet_flush(Eet_File *ef)
660EAPI int 683EAPI int
661eet_init(void) 684eet_init(void)
662{ 685{
686#ifdef HAVE_OPENSSL
687 /* Just load the crypto library error strings,
688 * SSL_load_error_strings() loads the crypto AND the SSL ones */
689 /* SSL_load_error_strings();*/
690 static int call_once = 0;
691
692 if (call_once == 0)
693 {
694 call_once = 1;
695 ERR_load_crypto_strings();
696 }
697
698#endif
663 return ++eet_initcount; 699 return ++eet_initcount;
664} 700}
665 701
@@ -738,6 +774,7 @@ eet_internal_read2(Eet_File *ef)
738 int bytes_directory_entries; 774 int bytes_directory_entries;
739 int num_dictionary_entries; 775 int num_dictionary_entries;
740 int bytes_dictionary_entries; 776 int bytes_dictionary_entries;
777 int signature_base_offset;
741 int i; 778 int i;
742 779
743 index += sizeof(int); 780 index += sizeof(int);
@@ -787,6 +824,8 @@ eet_internal_read2(Eet_File *ef)
787 if (eet_test_close(!ef->header->directory->nodes, ef)) 824 if (eet_test_close(!ef->header->directory->nodes, ef))
788 return NULL; 825 return NULL;
789 826
827 signature_base_offset = 0;
828
790 /* actually read the directory block - all of it, into ram */ 829 /* actually read the directory block - all of it, into ram */
791 for (i = 0; i < num_directory_entries; ++i) 830 for (i = 0; i < num_directory_entries; ++i)
792 { 831 {
@@ -850,6 +889,10 @@ eet_internal_read2(Eet_File *ef)
850 if (efn->data) 889 if (efn->data)
851 memcpy(efn->data, ef->data + efn->offset, efn->size); 890 memcpy(efn->data, ef->data + efn->offset, efn->size);
852 } 891 }
892
893 /* compute the possible position of a signature */
894 if (signature_base_offset < efn->offset + efn->size)
895 signature_base_offset = efn->offset + efn->size;
853 } 896 }
854 897
855 ef->ed = NULL; 898 ef->ed = NULL;
@@ -906,9 +949,35 @@ eet_internal_read2(Eet_File *ef)
906 ef->ed->all[j].hash = hash; 949 ef->ed->all[j].hash = hash;
907 if (ef->ed->all[j].prev == -1) 950 if (ef->ed->all[j].prev == -1)
908 ef->ed->hash[hash] = j; 951 ef->ed->hash[hash] = j;
952
953 /* compute the possible position of a signature */
954 if (signature_base_offset < offset + ef->ed->all[j].len)
955 signature_base_offset = offset + ef->ed->all[j].len;
909 } 956 }
910 } 957 }
911 958
959 /* Check if the file is signed */
960 ef->x509_der = NULL;
961 ef->x509_length = 0;
962 if (signature_base_offset < ef->data_size)
963 {
964#ifdef HAVE_SIGNATURE
965 const unsigned char *buffer = ((const unsigned char*) ef->data) + signature_base_offset;
966 ef->x509_der = eet_identity_check(ef->data, signature_base_offset,
967 buffer, ef->data_size - signature_base_offset,
968 &ef->x509_length);
969
970 if (ef->x509_der == NULL)
971 {
972 ef->delete_me_now = 1;
973 eet_close(ef);
974 return NULL;
975 }
976#else
977 fprintf(stderr, "This file could be signed but you didn't compile the necessary code to check the signature.\n");
978#endif
979 }
980
912 return ef; 981 return ef;
913} 982}
914 983
@@ -1120,6 +1189,7 @@ eet_memopen_read(const void *data, size_t size)
1120 1189
1121 ef->ed = NULL; 1190 ef->ed = NULL;
1122 ef->path = NULL; 1191 ef->path = NULL;
1192 ef->key = NULL;
1123 ef->magic = EET_MAGIC_FILE; 1193 ef->magic = EET_MAGIC_FILE;
1124 ef->references = 1; 1194 ef->references = 1;
1125 ef->mode = EET_FILE_MODE_READ; 1195 ef->mode = EET_FILE_MODE_READ;
@@ -1229,6 +1299,7 @@ eet_open(const char *file, Eet_File_Mode mode)
1229 1299
1230 /* fill some of the members */ 1300 /* fill some of the members */
1231 ef->fp = fp; 1301 ef->fp = fp;
1302 ef->key = NULL;
1232 ef->readfp = NULL; 1303 ef->readfp = NULL;
1233 ef->path = ((char *)ef) + sizeof(Eet_File); 1304 ef->path = ((char *)ef) + sizeof(Eet_File);
1234 memcpy(ef->path, file, file_len); 1305 memcpy(ef->path, file, file_len);
@@ -1297,6 +1368,32 @@ eet_mode_get(Eet_File *ef)
1297 return ef->mode; 1368 return ef->mode;
1298} 1369}
1299 1370
1371EAPI const void *
1372eet_identity_x509(Eet_File *ef, int *der_length)
1373{
1374 if (!ef->x509_der) return NULL;
1375
1376 if (der_length) *der_length = ef->x509_length;
1377 return ef->x509_der;
1378}
1379
1380EAPI Eet_Error
1381eet_identity_set(Eet_File *ef, Eet_Key *key)
1382{
1383 Eet_Key *tmp = ef->key;
1384
1385 if (!ef) return EET_ERROR_BAD_OBJECT;
1386
1387 ef->key = key;
1388 eet_identity_ref(ef->key);
1389 eet_identity_unref(tmp);
1390
1391 /* flags that writes are pending */
1392 ef->writes_pending = 1;
1393
1394 return EET_ERROR_NONE;
1395}
1396
1300EAPI Eet_Error 1397EAPI Eet_Error
1301eet_close(Eet_File *ef) 1398eet_close(Eet_File *ef)
1302{ 1399{
@@ -1312,6 +1409,9 @@ eet_close(Eet_File *ef)
1312 /* flush any writes */ 1409 /* flush any writes */
1313 err = eet_flush2(ef); 1410 err = eet_flush2(ef);
1314 1411
1412 eet_identity_unref(ef->key);
1413 ef->key = NULL;
1414
1315 /* if not urgent to delete it - dont free it - leave it in cache */ 1415 /* if not urgent to delete it - dont free it - leave it in cache */
1316 if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ)) 1416 if ((!ef->delete_me_now) && (ef->mode == EET_FILE_MODE_READ))
1317 return EET_ERROR_NONE; 1417 return EET_ERROR_NONE;
diff --git a/legacy/eet/src/tests/cert.pem b/legacy/eet/src/tests/cert.pem
new file mode 100644
index 0000000000..3265462d7b
--- /dev/null
+++ b/legacy/eet/src/tests/cert.pem
@@ -0,0 +1,22 @@
1-----BEGIN CERTIFICATE-----
2MIIDmTCCAwKgAwIBAgIJAIKWPcLUT5FAMA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD
3VQQGEwJGUjEWMBQGA1UECBMNSWxlLURlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMx
4FjAUBgNVBAoTDUVubGlnaHRlbm1lbnQxDjAMBgNVBAsTBVRlc3RzMQ0wCwYDVQQD
5EwRCQUlMMSIwIAYJKoZIhvcNAQkBFhNjZWRyaWMuYmFpbEBmcmVlLmZyMB4XDTA4
6MDczMDEzNDU1OVoXDTA5MDczMDEzNDU1OVowgZAxCzAJBgNVBAYTAkZSMRYwFAYD
7VQQIEw1JbGUtRGUtRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczEWMBQGA1UEChMNRW5s
8aWdodGVubWVudDEOMAwGA1UECxMFVGVzdHMxDTALBgNVBAMTBEJBSUwxIjAgBgkq
9hkiG9w0BCQEWE2NlZHJpYy5iYWlsQGZyZWUuZnIwgZ8wDQYJKoZIhvcNAQEBBQAD
10gY0AMIGJAoGBAMiE486eROKePG0/639D4XTTDR9XSRWp1xqZzq7P+jjWRFbZ/MWV
11IVzkc4MRm83UOolbPj76LjM10cseaVAhK7G9CHp2dur4alWvdCXPH5Q+LPOFS9gM
12x0Jz9EZeHHOHZKLyJdKSmot+zluwJTLe081RRUwzNKct6JrVVG/7SmITAgMBAAGj
13gfgwgfUwHQYDVR0OBBYEFEFar6doT5ImL2rf0rJX7EYQqtYQMIHFBgNVHSMEgb0w
14gbqAFEFar6doT5ImL2rf0rJX7EYQqtYQoYGWpIGTMIGQMQswCQYDVQQGEwJGUjEW
15MBQGA1UECBMNSWxlLURlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxFjAUBgNVBAoT
16DUVubGlnaHRlbm1lbnQxDjAMBgNVBAsTBVRlc3RzMQ0wCwYDVQQDEwRCQUlMMSIw
17IAYJKoZIhvcNAQkBFhNjZWRyaWMuYmFpbEBmcmVlLmZyggkAgpY9wtRPkUAwDAYD
18VR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCpZJhk8BgQh0foiMkOwOMKvObq
19GxAzqjbr7iU9tEvJgwukCBv59ndBM0B5l5ybQdIYWQJOfZE1HTvB60swZMwqap9X
205QXgewymuXiVk+roVh34wg8Pg8F588G2BtLIoujY/gN3WJQR7YPD34iTPc4koV+A
214vs6nmL6wtW21+hsaw==
22-----END CERTIFICATE-----
diff --git a/legacy/eet/src/tests/eet_suite.c b/legacy/eet/src/tests/eet_suite.c
index 003dfa5c75..c52b15c950 100644
--- a/legacy/eet/src/tests/eet_suite.c
+++ b/legacy/eet/src/tests/eet_suite.c
@@ -1,10 +1,17 @@
1#include <sys/types.h>
2#include <sys/stat.h>
1#include <stdlib.h> 3#include <stdlib.h>
2#include <string.h> 4#include <string.h>
3#include <strings.h> 5#include <strings.h>
4#include <stdio.h> 6#include <stdio.h>
7#include <fcntl.h>
5 8
6#include <check.h> 9#include <check.h>
7 10
11#ifdef HAVE_CONFIG_H
12# include <config.h>
13#endif
14
8#include "eet_suite.h" 15#include "eet_suite.h"
9 16
10START_TEST(eet_test_init) 17START_TEST(eet_test_init)
@@ -1146,6 +1153,77 @@ START_TEST(eet_small_image)
1146} 1153}
1147END_TEST 1154END_TEST
1148 1155
1156START_TEST(eet_identity_simple)
1157{
1158 const char *buffer = "Here is a string of data to save !";
1159 const void *tmp;
1160 Eet_File *ef;
1161 Eet_Key *k;
1162 char *test;
1163 char *file = strdup("/tmp/eet_suite_testXXXXXX");
1164 int size;
1165 int fd;
1166
1167 eet_init();
1168
1169 mktemp(file);
1170 chdir("src/tests");
1171
1172 /* Sign an eet file. */
1173 ef = eet_open(file, EET_FILE_MODE_WRITE);
1174 fail_if(!ef);
1175
1176 fail_if(!eet_write(ef, "keys/tests", buffer, strlen(buffer) + 1, 0));
1177
1178 k = eet_identity_open("cert.pem", "key.pem", NULL);
1179 fail_if(!k);
1180
1181 fail_if(eet_identity_set(ef, k) != EET_ERROR_NONE);
1182
1183 eet_close(ef);
1184
1185 /* Open a signed file. */
1186 ef = eet_open(file, EET_FILE_MODE_READ);
1187 fail_if(!ef);
1188
1189 test = eet_read(ef, "keys/tests", &size);
1190 fail_if(!test);
1191 fail_if(size != strlen(buffer) + 1);
1192
1193 fail_if(memcmp(test, buffer, strlen(buffer) + 1) != 0);
1194
1195 tmp = eet_identity_x509(ef, &size);
1196 fail_if(tmp == NULL);
1197
1198 eet_close(ef);
1199
1200 /* As we are changing file contain in less than 1s, this could get unnoticed
1201 by eet cache system. */
1202 eet_clearcache();
1203
1204 /* Corrupting the file. */
1205 fd = open(file, O_WRONLY);
1206 fail_if(fd < 0);
1207
1208 fail_if(lseek(fd, 200, SEEK_SET) != 200);
1209 fail_if(write(fd, "42", 2) != 2);
1210 fail_if(lseek(fd, 50, SEEK_SET) != 50);
1211 fail_if(write(fd, "42", 2) != 2);
1212 fail_if(lseek(fd, 88, SEEK_SET) != 88);
1213 fail_if(write(fd, "42", 2) != 2);
1214
1215 close(fd);
1216
1217 /* Attempt to open a modified file. */
1218 ef = eet_open(file, EET_FILE_MODE_READ);
1219 fail_if(ef);
1220
1221 fail_if(unlink(file) != 0);
1222
1223 eet_shutdown();
1224}
1225END_TEST
1226
1149Suite * 1227Suite *
1150eet_suite(void) 1228eet_suite(void)
1151{ 1229{
@@ -1175,6 +1253,12 @@ eet_suite(void)
1175 tcase_add_test(tc, eet_small_image); 1253 tcase_add_test(tc, eet_small_image);
1176 suite_add_tcase(s, tc); 1254 suite_add_tcase(s, tc);
1177 1255
1256#ifdef HAVE_SIGNATURE
1257 tc = tcase_create("Eet Identity");
1258 tcase_add_test(tc, eet_identity_simple);
1259 suite_add_tcase(s, tc);
1260#endif
1261
1178 return s; 1262 return s;
1179} 1263}
1180 1264
diff --git a/legacy/eet/src/tests/key.pem b/legacy/eet/src/tests/key.pem
new file mode 100644
index 0000000000..74763ca8c8
--- /dev/null
+++ b/legacy/eet/src/tests/key.pem
@@ -0,0 +1,15 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIICXAIBAAKBgQDIhOPOnkTinjxtP+t/Q+F00w0fV0kVqdcamc6uz/o41kRW2fzF
3lSFc5HODEZvN1DqJWz4++i4zNdHLHmlQISuxvQh6dnbq+GpVr3Qlzx+UPizzhUvY
4DMdCc/RGXhxzh2Si8iXSkpqLfs5bsCUy3tPNUUVMMzSnLeia1VRv+0piEwIDAQAB
5AoGAfLLHyNJ8HEIzae16UmawaqplWrw5YxOABbbo5aXJAledoDVoEKexW8dmXngw
64Eu/K3RmvVtwJ8CsexiqfX5jYMU+YKRbww6Vqr/punIUhiEHVarHMFKG9yo14qSa
7z2xPgXvC5p7/Rhci+rAUp36S5kIHch5sLhEEcJayymyzDyECQQD/5B3JdpcovrSI
8+nyZ8Iub2+I3f3uox6m1DKxHead26ICoIr7VCnPV5J1gLIB2MofVCbKhmy4PNi5a
90QdvazJfAkEAyJq9Y+9SQ4sCOVDrFklJxhXuZE4WbnR32XsBdnQ9dauo0E2vDVkv
106mHnzMWroTjLv4hH5nufE5NvMo8PNGB0zQJAFOKkf737JmsyRv/Szamxa14t/4Ob
11LzJkqo9HPGo0feMKJS74zmCVBb8sDR50ubD0HzI0bzZAMyOj8uuepLxmFwJAH+RR
125bhfeLN52AjgRvvBycckzjeH42mKwD2I/v794l43CV7ATLv4HSgRhQGMBqaT5dBR
13tffDU4Zl8EDEJwyKpQJBAJ2NNacURTyavU699QJOIdGAsA4KXici8H3PuuWMtHLR
14RKdPFeaCRn+9p7Tglf0rH9hUGOpUXHYD3+ECt6gnVDc=
15-----END RSA PRIVATE KEY-----