package org.commcare.models.legacy; import android.database.sqlite.SQLiteCursor; import android.database.sqlite.SQLiteCursorDriver; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQuery; import org.commcare.models.encryption.CipherPool; import org.commcare.core.encryption.CryptUtil; import org.commcare.modern.database.DatabaseHelper; import org.commcare.modern.models.EncryptedModel; import javax.crypto.Cipher; /** * @author ctsims */ public class DecryptingCursor extends SQLiteCursor { final Cipher cipher; final EncryptedModel model; final CipherPool pool; public DecryptingCursor(SQLiteDatabase db, SQLiteCursorDriver driver, String editTable, SQLiteQuery query, EncryptedModel model, CipherPool pool) { super(db, driver, editTable, query); this.model = model; this.pool = pool; this.cipher = pool.borrow(); } @Override public byte[] getBlob(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getBlob(columnIndex); } else { return decrypt(columnIndex); } } @Override public double getDouble(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getDouble(columnIndex); } else { return Double.valueOf(new String(decrypt(columnIndex))); } } @Override public float getFloat(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getFloat(columnIndex); } else { return Float.valueOf(new String(decrypt(columnIndex))); } } @Override public int getInt(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getInt(columnIndex); } else { return Integer.valueOf(new String(decrypt(columnIndex))); } } @Override public long getLong(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getLong(columnIndex); } else { return Long.valueOf(new String(decrypt(columnIndex))); } } @Override public short getShort(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getShort(columnIndex); } else { return Short.valueOf(new String(decrypt(columnIndex))); } } @Override public String getString(int columnIndex) { if (!isEncrypted(columnIndex)) { return super.getString(columnIndex); } else { return new String(decrypt(columnIndex)); } } private boolean isEncrypted(int columnIndex) { String column = this.getColumnName(columnIndex); if (model.isEncrypted(column)) { return true; } return (column.equals(DatabaseHelper.DATA_COL) && model.isBlobEncrypted()); } private byte[] decrypt(int columnIndex) { byte[] data = super.getBlob(columnIndex); return CryptUtil.decrypt(data, cipher); } @Override public void close() { super.close(); pool.remit(cipher); } }