diff options
author | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2010-04-22 12:31:19 +0000 |
---|---|---|
committer | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2010-04-22 12:31:19 +0000 |
commit | 5e5858f114918aa684fff6256c4c949e822635dd (patch) | |
tree | 5970bcf1f02569b4b5efc0f61c7acfeb1a6968aa /navit/file.c | |
parent | 72822d63ff76a24a026d7e49a1852a2a950c4f4a (diff) | |
download | navit-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.c | 85 |
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) { |