package org.commcare.android.db.legacy;
import java.io.IOException;
import javax.crypto.Cipher;
import org.commcare.android.crypt.CipherPool;
import org.commcare.android.crypt.CryptUtil;
import org.commcare.android.database.DbUtil;
import org.commcare.android.database.EncryptedModel;
import android.database.sqlite.SQLiteCursor;
import android.database.sqlite.SQLiteCursorDriver;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQuery;
/**
* @author ctsims
*
*/
public class DecryptingCursor extends SQLiteCursor {
Cipher cipher;
EncryptedModel model;
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();
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getBlob(int)
*/
@Override
public byte[] getBlob(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getBlob(columnIndex);
} else {
return decrypt(columnIndex);
}
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getDouble(int)
*/
@Override
public double getDouble(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getDouble(columnIndex);
} else {
return Double.valueOf(new String(decrypt(columnIndex)));
}
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getFloat(int)
*/
@Override
public float getFloat(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getFloat(columnIndex);
} else {
return Float.valueOf(new String(decrypt(columnIndex)));
}
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getInt(int)
*/
@Override
public int getInt(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getInt(columnIndex);
} else {
return Integer.valueOf(new String(decrypt(columnIndex)));
}
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getLong(int)
*/
@Override
public long getLong(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getLong(columnIndex);
} else {
return Long.valueOf(new String(decrypt(columnIndex)));
}
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getShort(int)
*/
@Override
public short getShort(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getShort(columnIndex);
} else {
return Short.valueOf(new String(decrypt(columnIndex)));
}
}
/*
* (non-Javadoc)
* @see android.database.AbstractWindowedCursor#getString(int)
*/
@Override
public String getString(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.getString(columnIndex);
} else {
return new String(decrypt(columnIndex));
}
}
/**
@Override
public boolean isBlob(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.isBlob(columnIndex);
}
}
@Override
public boolean isFloat(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.isFloat(columnIndex);
}
}
@Override
public boolean isLong(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.isLong(columnIndex);
}
}
@Override
public boolean isNull(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.isNull(columnIndex);
}
}
@Override
public boolean isString(int columnIndex) {
if(!isEncrypted(columnIndex)) {
return super.isString(columnIndex);
}
}
**/
private boolean isEncrypted(int columnIndex) {
String column = this.getColumnName(columnIndex);
if(model.isEncrypted(column)) {
return true;
} if(column.equals(DbUtil.DATA_COL)) {
return model.isBlobEncrypted();
}
return false;
}
private byte[] decrypt(int columnIndex) {
byte[] data = super.getBlob(columnIndex);
return CryptUtil.decrypt(data, cipher);
}
/* (non-Javadoc)
* @see android.database.sqlite.SQLiteCursor#close()
*/
@Override
public void close() {
super.close();
pool.remit(cipher);
}
}