summaryrefslogtreecommitdiff
path: root/navit/file.c
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-04-22 12:31:19 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-04-22 12:31:19 +0000
commit5e5858f114918aa684fff6256c4c949e822635dd (patch)
tree5970bcf1f02569b4b5efc0f61c7acfeb1a6968aa /navit/file.c
parent72822d63ff76a24a026d7e49a1852a2a950c4f4a (diff)
downloadnavit-5e5858f114918aa684fff6256c4c949e822635dd.tar.gz
Add:Core:Map encryption support
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@3188 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/file.c')
-rw-r--r--navit/file.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/navit/file.c b/navit/file.c
index b41d2695b..9b5e849ed 100644
--- a/navit/file.c
+++ b/navit/file.c
@@ -36,6 +36,15 @@
#include "atom.h"
#include "config.h"
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#endif
+
+
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
@@ -44,6 +53,7 @@
#define O_BINARY 0
#endif
+#define CACHE_SIZE (10*1024*1024)
#ifdef CACHE_SIZE
static GHashTable *file_name_hash;
#endif
@@ -301,6 +311,81 @@ file_data_read_compressed(struct file *file, long long offset, int size, int siz
return ret;
}
+unsigned char *
+file_data_read_encrypted(struct file *file, long long offset, int size, int size_uncomp, int compressed, char *passwd)
+{
+#ifdef HAVE_LIBCRYPTO
+ void *ret;
+ unsigned char *buffer = 0;
+ uLongf destLen=size_uncomp;
+
+ if (file_cache) {
+ struct file_cache_id id={offset,size,file->name_id,1};
+ ret=cache_lookup(file_cache,&id);
+ if (ret)
+ return ret;
+ ret=cache_insert_new(file_cache,&id,size_uncomp);
+ } else
+ ret=g_malloc(size_uncomp);
+ lseek(file->fd, offset, SEEK_SET);
+
+ buffer = (unsigned char *)g_malloc(size);
+ if (read(file->fd, buffer, size) != size) {
+ g_free(ret);
+ ret=NULL;
+ } else {
+ unsigned char key[34], salt[8], verify[2], counter[16], xor[16], mac[10], mactmp[20], *datap;
+ int overhead=sizeof(salt)+sizeof(verify)+sizeof(mac);
+ int esize=size-overhead;
+ PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), (unsigned char *)buffer, 8, 1000, 34, key);
+ if (key[32] == buffer[8] && key[33] == buffer[9] && esize >= 0) {
+ AES_KEY aeskey;
+ AES_set_encrypt_key(key, 128, &aeskey);
+ datap=buffer+sizeof(salt)+sizeof(verify);
+ memset(counter, 0, sizeof(counter));
+ while (esize > 0) {
+ int i,curr_size,idx=0;
+ do {
+ counter[idx]++;
+ } while (!counter[idx++]);
+ AES_encrypt(counter, xor, &aeskey);
+ curr_size=esize;
+ if (curr_size > sizeof(xor))
+ curr_size=sizeof(xor);
+ for (i = 0 ; i < curr_size ; i++)
+ *datap++^=xor[i];
+ esize-=curr_size;
+ }
+ size-=overhead;
+ datap=buffer+sizeof(salt)+sizeof(verify);
+ if (compressed) {
+ if (uncompress_int(ret, &destLen, (Bytef *)datap, size) != Z_OK) {
+ dbg(0,"uncompress failed\n");
+ g_free(ret);
+ ret=NULL;
+ }
+ } else {
+ if (size == destLen)
+ memcpy(ret, destLen, buffer);
+ else {
+ dbg(0,"memcpy failed\n");
+ g_free(ret);
+ ret=NULL;
+ }
+ }
+ } else {
+ g_free(ret);
+ ret=NULL;
+ }
+ }
+ g_free(buffer);
+
+ return ret;
+#else
+ return NULL;
+#endif
+}
+
void
file_data_free(struct file *file, unsigned char *data)
{