/* * * Panbox - encryption for cloud storage * Copyright (C) 2014-2015 by Fraunhofer SIT and Sirrix AG * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Additonally, third party code may be provided with notices and open source * licenses from communities and third parties that govern the use of those * portions, and any licenses granted hereunder do not alter any rights and * obligations you may have under such open source licenses, however, the * disclaimer of warranty and limitation of liability provisions of the GPLv3 * will apply to all the product. * */ package org.panbox.core.crypto; import java.io.File; import java.util.ArrayList; import java.util.Map; import org.panbox.PanboxConstants; import org.panbox.core.LimitedHashMap; import org.panbox.mobile.android.dropbox.csp.DropboxConnector; import org.panbox.mobile.android.dropbox.vfs.DropboxVirtualFile; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; public class AndroidObfuscatorIVPool extends AbstractObfuscatorIVPool { // private static AndroidObfuscatorIVPool instance = null; private DropboxConnector dbc = null; private static IVPoolCacheDBHelper dbHelper = null; private static SQLiteDatabase cacheDB = null; // public static AndroidObfuscatorIVPool getInstance(DropboxConnector dbc, // Context ctx) { // if (null == instance) { // //instance = new AndroidObfuscatorIVPool(dbc); // instance = new AndroidObfuscatorIVPool(); // dbHelper = new IVPoolCacheDBHelper(ctx); // cacheDB = dbHelper.getWritableDatabase(); // } // return instance; // } public AndroidObfuscatorIVPool(DropboxConnector dbc, Context ctx) { dbHelper = new IVPoolCacheDBHelper(ctx); cacheDB = dbHelper.getWritableDatabase(); this.dbc = dbc; } @Override public byte[] getCachedIV(String lookupHash, String sharePath) { // 1. try to fetch it from cache in memory byte[] iv = super.getCachedIV(lookupHash, sharePath); if (null != iv) { // System.err.println("fetch memory cache: " + lookupHash); return iv; } // 2. create db connection to cache db and try to fetch the IV from // there Cursor c = cacheDB.query(IVPoolCacheDBHelper.TABLE_IV_CACHE, new String[] { IVPoolCacheDBHelper.COLUMN_IV }, IVPoolCacheDBHelper.COLUMN_HASH + "=? and " + IVPoolCacheDBHelper.COLUMN_SHARE + "=?", new String[] { lookupHash, sharePath }, null, null, null); if (c != null) { if (c.moveToFirst()) { iv = c.getBlob(0); // System.err.println("fetch sqlite DB cache: " + lookupHash); } c.close(); return iv; } else { System.err.println("Cannot query IV Pool cache.db"); } // 3. (optional and we skip it for now): try single fetch (i.e. just // this one file) if possible return null; } @Override public void fetchIVPool(String absolutePath, String shareName) { long timeBefore = System.currentTimeMillis(); String ivPath = absolutePath + File.separator + Obfuscator.IV_POOL_PATH; ArrayList<DropboxVirtualFile> files = dbc.listFiles(ivPath, null); LimitedHashMap<String, byte[]> ivs = new LimitedHashMap<String, byte[]>( PanboxConstants.OBFUSCATOR_IV_POOL_SIZE); cacheDB.beginTransactionNonExclusive(); for (DropboxVirtualFile df : files) { if (!df.isDirectory()) { // ignore files, we only react on directories a-z and 0-9 continue; } ArrayList<String> subDirFiles = dbc.list(ivPath + File.separator + df.getFileName()); String sql = "Insert or Replace into " + IVPoolCacheDBHelper.TABLE_IV_CACHE + " (" + IVPoolCacheDBHelper.COLUMN_SHARE + ", " + IVPoolCacheDBHelper.COLUMN_HASH + ", " + IVPoolCacheDBHelper.COLUMN_IV + ") values(?,?,?)"; SQLiteStatement insert = cacheDB.compileStatement(sql); for (String fileName : subDirFiles) { Map.Entry<String, byte[]> e = splitFilename(fileName); ivs.put(e.getKey(), e.getValue()); // create persistant cache insert.bindString(1, shareName); insert.bindString(2, e.getKey()); insert.bindBlob(3, e.getValue()); insert.execute(); insert.clearBindings(); // ContentValues values = new ContentValues(); // values.put(IVPoolCacheDBHelper.COLUMN_HASH, e.getKey()); // values.put(IVPoolCacheDBHelper.COLUMN_IV, e.getValue()); // // String whereClause = IVPoolCacheDBHelper.COLUMN_HASH +"=?"; // String[] whereArgs = new String[]{e.getKey()}; // int updatedRows = // cacheDB.update(IVPoolCacheDBHelper.TABLE_IV_CACHE, values, // whereClause, whereArgs); // // if(updatedRows == 0) // { // cacheDB.insert(IVPoolCacheDBHelper.TABLE_IV_CACHE, // null, values); // } } } try { cacheDB.setTransactionSuccessful(); } catch (IllegalStateException e) { e.printStackTrace(); } finally { cacheDB.endTransaction(); } // cacheDB.close(); long timeAfter = System.currentTimeMillis(); System.err.println("Time needed for IV Pool creation: " + (timeAfter - timeBefore)); // cache it in memory this.ivPool = ivs; } }