package uk.ac.cam.db538.cryptosms.storage; import java.io.IOException; import java.nio.ByteBuffer; import uk.ac.cam.db538.cryptosms.storage.Header; import uk.ac.cam.db538.cryptosms.storage.Storage; import uk.ac.cam.db538.cryptosms.storage.StorageFileException; import uk.ac.cam.db538.cryptosms.crypto.Encryption; import uk.ac.cam.db538.cryptosms.crypto.EncryptionNone; import uk.ac.cam.db538.cryptosms.crypto.EncryptionInterface.EncryptionException; import uk.ac.cam.db538.cryptosms.utils.LowLevel; import junit.framework.TestCase; public class Header_Test extends TestCase { protected void setUp() throws Exception { super.setUp(); EncryptionNone.initEncryption(); Common.clearStorageFile(); } protected void tearDown() throws Exception { super.tearDown(); Common.closeStorageFile(); } public void testConstruction() throws StorageFileException, IOException { // create a header Header header = Header.createHeader(); header.setKeyId(123); header.setVersion(12); header.setIndexEmpty(13L); header.setIndexConversations(15L); header.saveToFile(); // force it to be re-read from file Header.forceClearCache(); header = Header.getHeader(); assertEquals(header.getKeyId(), 123); assertEquals(header.getVersion(), 12); assertEquals(header.getIndexEmpty(), 13L); assertEquals(header.getIndexConversations(), 15L); } public void testIndices() throws StorageFileException, IOException { // INDICES OUT OF BOUNDS Header header = Header.createHeader(); // indexFree try { header.setIndexEmpty(0x0100000000L); assertTrue(false); } catch (IndexOutOfBoundsException ex) { } try { header.setIndexEmpty(-1L); assertTrue(false); } catch (IndexOutOfBoundsException ex) { } // indexConversation try { header.setIndexConversations(0x0100000000L); assertTrue(false); } catch (IndexOutOfBoundsException ex) { } try { header.setIndexConversations(-1L); assertTrue(false); } catch (IndexOutOfBoundsException ex) { } // version try { header.setVersion(0x100); assertTrue(false); } catch (IndexOutOfBoundsException ex) { } } public void testCreateData() throws StorageFileException, IOException, EncryptionException { long indexFree = 25L; long indexConversation = 13L; int version = 32; int keyId = 244; Header header = Header.createHeader(); header.setKeyId(keyId); header.setIndexEmpty(indexFree); header.setIndexConversations(indexConversation); header.setVersion(version); header.saveToFile(); byte[] dataAll = Storage.getStorage().getEntry(0); // chunk length assertEquals(dataAll.length, Storage.CHUNK_SIZE); // plain header assertEquals(dataAll[0], (byte) 0x53); // S assertEquals(dataAll[1], (byte) 0x4D); // M assertEquals(dataAll[2], (byte) 0x53); // S assertEquals(dataAll[3], (byte) version); // Version // decrypt the encoded part ByteBuffer buf = ByteBuffer.allocate(Storage.CHUNK_SIZE - 16); buf.put(dataAll, 16, Storage.CHUNK_SIZE - 16); byte[] dataPlain = Encryption.getEncryption().decryptSymmetricWithMasterKey(buf.array()); // check the keyId assertEquals(LowLevel.getUnsignedByte(dataPlain[0]), keyId); // check the indices assertEquals(LowLevel.getUnsignedInt(dataPlain, Storage.CHUNK_SIZE - 16 - Encryption.SYM_OVERHEAD - 8), indexFree); assertEquals(LowLevel.getUnsignedInt(dataPlain, Storage.CHUNK_SIZE - 16 - Encryption.SYM_OVERHEAD - 4), indexConversation); } public void testParseData() throws IOException, StorageFileException, EncryptionException { long indexFree = 25L; long indexConversation = 13L; int version = 17; int keyId = 244; byte[] dataPlain = new byte[Storage.CHUNK_SIZE - 16 - Encryption.SYM_OVERHEAD]; dataPlain[0] = (byte)keyId; System.arraycopy(LowLevel.getBytesUnsignedInt(indexFree), 0, dataPlain, Storage.CHUNK_SIZE - 16 - Encryption.SYM_OVERHEAD - 8, 4); System.arraycopy(LowLevel.getBytesUnsignedInt(indexConversation), 0, dataPlain, Storage.CHUNK_SIZE - 16 - Encryption.SYM_OVERHEAD - 4, 4); byte[] dataEncrypted = Encryption.getEncryption().encryptSymmetricWithMasterKey(dataPlain); byte[] dataAll = new byte[Storage.CHUNK_SIZE]; System.arraycopy(dataEncrypted, 0, dataAll, 16, Storage.CHUNK_SIZE - 16); // wrong header (SMS) dataAll[0] = 0x53; // S dataAll[1] = 0x53; // S dataAll[2] = 0x53; // S try { // inject it in the file Storage.getStorage().setEntry(0, dataAll); Header.forceClearCache(); Header.getHeader(); assertTrue(false); } catch (StorageFileException ex) { } // fixed, version set dataAll[1] = 0x4D; // M dataAll[3] = (byte) version; Storage.getStorage().setEntry(0, dataAll); Header.forceClearCache(); Header header = null; try { header = Header.getHeader(); assertEquals(keyId, header.getKeyId()); assertEquals(indexFree, header.getIndexEmpty()); assertEquals(indexConversation, header.getIndexConversations()); assertEquals(version, header.getVersion()); } catch (StorageFileException ex) { assertTrue(false); } } }