/* * Universal Password Manager * Copyright (C) 2005-2013 Adrian Smith * * This file is part of Universal Password Manager. * * Universal Password Manager 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 2 of the License, or * (at your option) any later version. * * Universal Password Manager 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 Universal Password Manager; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package com._17od.upm.database; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import junit.framework.TestCase; import com._17od.upm.crypto.CryptoException; import com._17od.upm.crypto.DESDecryptionService; import com._17od.upm.crypto.EncryptionService; import com._17od.upm.crypto.InvalidPasswordException; public class PasswordDatabasePersistenceTest extends TestCase { private String password = "password"; private PasswordDatabasePersistence passwordDatabasePersistence; public void setUp() { passwordDatabasePersistence = new PasswordDatabasePersistence(); } public void testLoadVer2DB() throws ProblemReadingDatabaseFile, CryptoException, IOException, InvalidPasswordException { File f = createVer2Db(); PasswordDatabase db = passwordDatabasePersistence.load(f, password.toCharArray()); assertEquals(4, db.getRevision()); assertEquals("rl", db.getDbOptions().getRemoteLocation()); assertEquals("adbe", db.getDbOptions().getAuthDBEntry()); assertEquals(1, db.getAccounts().size()); AccountInformation account = (AccountInformation) db.getAccounts().get(0); assertEquals("test account", account.getAccountName()); assertEquals("auserid", new String(account.getUserId())); assertEquals("apassword", new String(account.getPassword())); assertEquals("http://www.a.com", new String(account.getUrl())); assertEquals("some notes", new String(account.getNotes())); } public void testLoadVer110DB() throws ProblemReadingDatabaseFile, CryptoException, IOException, InvalidPasswordException { File f = createVer110Db(); PasswordDatabase db = passwordDatabasePersistence.load(f, password.toCharArray()); assertEquals(6, db.getRevision()); assertEquals("qwe", db.getDbOptions().getRemoteLocation()); assertEquals("fdef", db.getDbOptions().getAuthDBEntry()); assertEquals(1, db.getAccounts().size()); AccountInformation account = (AccountInformation) db.getAccounts().get(0); assertEquals("test account110", account.getAccountName()); assertEquals("auserid110", new String(account.getUserId())); assertEquals("apassword110", new String(account.getPassword())); assertEquals("http://www.a.com/110", new String(account.getUrl())); assertEquals("some notes110", new String(account.getNotes())); } public void testLoadVer100DB() throws ProblemReadingDatabaseFile, CryptoException, IOException, InvalidPasswordException { File f = createVer100Db(); PasswordDatabase db = passwordDatabasePersistence.load(f, password.toCharArray()); assertEquals(1, db.getAccounts().size()); AccountInformation account = (AccountInformation) db.getAccounts().get(0); assertEquals("test account100", account.getAccountName()); assertEquals("auserid100", new String(account.getUserId())); assertEquals("apassword100", new String(account.getPassword())); assertEquals("http://www.a.com/100", new String(account.getUrl())); assertEquals("some notes100", new String(account.getNotes())); } private File createVer100Db() throws IOException, CryptoException { byte[] b = createVer100DbBytes(); return saveToFile(b); } private File createVer110Db() throws IOException, CryptoException { byte[] b = createVer110DbBytes(); return saveToFile(b); } private File createVer2Db() throws IOException, CryptoException { byte[] b = createVer2DbBytes(); return saveToFile(b); } private byte[] createVer100DbBytes() throws IOException, CryptoException { // SALT [DB_HEADER ACCOUNTS] ByteArrayOutputStream partToEncryptOS = new ByteArrayOutputStream(); partToEncryptOS.write("00011".getBytes()); // db version: major partToEncryptOS.write("00010".getBytes()); // db version: minor partToEncryptOS.write("00010".getBytes()); // db version: patch partToEncryptOS.write("0015test account100".getBytes()); // account name partToEncryptOS.write("0010auserid100".getBytes()); // userid partToEncryptOS.write("0012apassword100".getBytes()); // password partToEncryptOS.write("0020http://www.a.com/100".getBytes()); // url partToEncryptOS.write("0013some notes100".getBytes()); // notes partToEncryptOS.close(); byte[] salt = DESDecryptionService.generateSalt(); byte[] encryptedPart = DESDecryptionService.encrypt(password.toCharArray(), salt, partToEncryptOS.toByteArray()); ByteArrayOutputStream dbOS = new ByteArrayOutputStream(); dbOS.write(salt); // salt dbOS.write(encryptedPart); // encrypted body dbOS.close(); return dbOS.toByteArray(); } private byte[] createVer110DbBytes() throws IOException, CryptoException { // SALT [DB_HEADER DB_REVISION DB_OPTIONS ACCOUNTS] ByteArrayOutputStream partToEncryptOS = new ByteArrayOutputStream(); partToEncryptOS.write("00011".getBytes()); // db version: major partToEncryptOS.write("00011".getBytes()); // db version: minor partToEncryptOS.write("00010".getBytes()); // db version: patch partToEncryptOS.write("00016".getBytes()); // revision partToEncryptOS.write("0003qwe".getBytes()); // remoteLocation partToEncryptOS.write("0004fdef".getBytes()); // authDBEntry partToEncryptOS.write("0015test account110".getBytes()); // account name partToEncryptOS.write("0010auserid110".getBytes()); // userid partToEncryptOS.write("0012apassword110".getBytes()); // password partToEncryptOS.write("0020http://www.a.com/110".getBytes()); // url partToEncryptOS.write("0013some notes110".getBytes()); // notes partToEncryptOS.close(); byte[] salt = DESDecryptionService.generateSalt(); byte[] encryptedPart = DESDecryptionService.encrypt(password.toCharArray(), salt, partToEncryptOS.toByteArray()); ByteArrayOutputStream dbOS = new ByteArrayOutputStream(); dbOS.write(salt); // salt dbOS.write(encryptedPart); // encrypted body dbOS.close(); return dbOS.toByteArray(); } private byte[] createVer2DbBytes() throws CryptoException, IOException { EncryptionService ec = new EncryptionService(password.toCharArray()); // MAGIC_NUMBER DB_VERSION SALT [DB_REVISION DB_OPTIONS ACCOUNTS] ByteArrayOutputStream partToEncryptOS = new ByteArrayOutputStream(); partToEncryptOS.write("00014".getBytes()); // revision partToEncryptOS.write("0002rl".getBytes()); // remoteLocation partToEncryptOS.write("0004adbe".getBytes()); // authDBEntry partToEncryptOS.write("0012test account".getBytes()); // account name partToEncryptOS.write("0007auserid".getBytes()); // userid partToEncryptOS.write("0009apassword".getBytes()); // password partToEncryptOS.write("0016http://www.a.com".getBytes()); // url partToEncryptOS.write("0010some notes".getBytes()); // notes partToEncryptOS.close(); byte[] encryptedPart = ec.encrypt(partToEncryptOS.toByteArray()); ByteArrayOutputStream dbOS = new ByteArrayOutputStream(); dbOS.write("UPM".getBytes()); // magic number dbOS.write(0x2); // db version (2) dbOS.write(ec.getSalt()); // salt dbOS.write(encryptedPart); // encrypted body dbOS.close(); return dbOS.toByteArray(); } private File saveToFile(byte[] b) throws IOException { File f = File.createTempFile("upm", "upm"); FileOutputStream fos = new FileOutputStream(f); fos.write(b); fos.close(); return f; } }