use of com.keepassdroid.stream.LEDataInputStream in project KeePassDX by Kunzisoft.
the class ImporterV4 method openDatabase.
@Override
public PwDatabaseV4 openDatabase(InputStream inStream, String password, InputStream keyInputStream, UpdateStatus status, long roundsFix) throws IOException, InvalidDBException {
db = createDB();
PwDbHeaderV4 header = new PwDbHeaderV4(db);
db.binPool.clear();
PwDbHeaderV4.HeaderAndHash hh = header.loadFromFile(inStream);
version = header.version;
hashOfHeader = hh.hash;
pbHeader = hh.header;
db.setMasterKey(password, keyInputStream);
db.makeFinalKey(header.masterSeed, db.kdfParameters, roundsFix);
CipherEngine engine;
Cipher cipher;
try {
engine = CipherFactory.getInstance(db.dataCipher);
db.dataEngine = engine;
cipher = engine.getCipher(Cipher.DECRYPT_MODE, db.finalKey, header.encryptionIV);
} catch (NoSuchAlgorithmException e) {
throw new IOException("Invalid algorithm.");
} catch (NoSuchPaddingException e) {
throw new IOException("Invalid algorithm.");
} catch (InvalidKeyException e) {
throw new IOException("Invalid algorithm.");
} catch (InvalidAlgorithmParameterException e) {
throw new IOException("Invalid algorithm.");
}
InputStream isPlain;
if (version < PwDbHeaderV4.FILE_VERSION_32_4) {
InputStream decrypted = AttachCipherStream(inStream, cipher);
LEDataInputStream dataDecrypted = new LEDataInputStream(decrypted);
byte[] storedStartBytes = null;
try {
storedStartBytes = dataDecrypted.readBytes(32);
if (storedStartBytes == null || storedStartBytes.length != 32) {
throw new InvalidPasswordException();
}
} catch (IOException e) {
throw new InvalidPasswordException();
}
if (!Arrays.equals(storedStartBytes, header.streamStartBytes)) {
throw new InvalidPasswordException();
}
isPlain = new HashedBlockInputStream(dataDecrypted);
} else {
// KDBX 4
LEDataInputStream isData = new LEDataInputStream(inStream);
byte[] storedHash = isData.readBytes(32);
if (!Arrays.equals(storedHash, hashOfHeader)) {
throw new InvalidDBException();
}
byte[] hmacKey = db.hmacKey;
byte[] headerHmac = PwDbHeaderV4.computeHeaderHmac(pbHeader, hmacKey);
byte[] storedHmac = isData.readBytes(32);
if (storedHmac == null || storedHmac.length != 32) {
throw new InvalidDBException();
}
// Mac doesn't match
if (!Arrays.equals(headerHmac, storedHmac)) {
throw new InvalidDBException();
}
HmacBlockInputStream hmIs = new HmacBlockInputStream(isData, true, hmacKey);
isPlain = AttachCipherStream(hmIs, cipher);
}
InputStream isXml;
if (db.compressionAlgorithm == PwCompressionAlgorithm.Gzip) {
isXml = new GZIPInputStream(isPlain);
} else {
isXml = isPlain;
}
if (version >= header.FILE_VERSION_32_4) {
LoadInnerHeader(isXml, header);
}
if (header.innerRandomStreamKey == null) {
assert (false);
throw new IOException("Invalid stream key.");
}
randomStream = PwStreamCipherFactory.getInstance(header.innerRandomStream, header.innerRandomStreamKey);
if (randomStream == null) {
throw new ArcFourException();
}
ReadXmlStreamed(isXml);
return db;
}
use of com.keepassdroid.stream.LEDataInputStream in project KeePassDX by Kunzisoft.
the class CipherTest method testCipherStreams.
public void testCipherStreams() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException {
final int MESSAGE_LENGTH = 1024;
byte[] key = new byte[32];
byte[] iv = new byte[16];
byte[] plaintext = new byte[MESSAGE_LENGTH];
rand.nextBytes(key);
rand.nextBytes(iv);
rand.nextBytes(plaintext);
CipherEngine aes = CipherFactory.getInstance(AesEngine.CIPHER_UUID);
Cipher encrypt = aes.getCipher(Cipher.ENCRYPT_MODE, key, iv);
Cipher decrypt = aes.getCipher(Cipher.DECRYPT_MODE, key, iv);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CipherOutputStream cos = new CipherOutputStream(bos, encrypt);
cos.write(plaintext);
cos.close();
byte[] secrettext = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(secrettext);
BetterCipherInputStream cis = new BetterCipherInputStream(bis, decrypt);
LEDataInputStream lis = new LEDataInputStream(cis);
byte[] decrypttext = lis.readBytes(MESSAGE_LENGTH);
assertArrayEquals("Encryption and decryption failed", plaintext, decrypttext);
}
use of com.keepassdroid.stream.LEDataInputStream in project KeePassDX by Kunzisoft.
the class PwDbHeaderV4 method loadFromFile.
/**
* Assumes the input stream is at the beginning of the .kdbx file
* @param is
* @throws IOException
* @throws InvalidDBVersionException
*/
public HeaderAndHash loadFromFile(InputStream is) throws IOException, InvalidDBVersionException {
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new IOException("No SHA-256 implementation");
}
ByteArrayOutputStream headerBOS = new ByteArrayOutputStream();
CopyInputStream cis = new CopyInputStream(is, headerBOS);
DigestInputStream dis = new DigestInputStream(cis, md);
LEDataInputStream lis = new LEDataInputStream(dis);
int sig1 = lis.readInt();
int sig2 = lis.readInt();
if (!matchesHeader(sig1, sig2)) {
throw new InvalidDBVersionException();
}
version = lis.readUInt();
if (!validVersion(version)) {
throw new InvalidDBVersionException();
}
boolean done = false;
while (!done) {
done = readHeaderField(lis);
}
byte[] hash = md.digest();
return new HeaderAndHash(headerBOS.toByteArray(), hash);
}
use of com.keepassdroid.stream.LEDataInputStream in project KeePassDX by Kunzisoft.
the class KdfParameters method deserialize.
public static KdfParameters deserialize(byte[] data) throws IOException {
ByteArrayInputStream bis = new ByteArrayInputStream(data);
LEDataInputStream lis = new LEDataInputStream(bis);
VariantDictionary d = VariantDictionary.deserialize(lis);
if (d == null) {
assert (false);
return null;
}
UUID uuid = Types.bytestoUUID(d.getByteArray(ParamUUID));
if (uuid == null) {
assert (false);
return null;
}
KdfParameters kdfP = new KdfParameters(uuid);
kdfP.copyTo(d);
return kdfP;
}
Aggregations