use of com.keepassdroid.database.PwDbHeaderV4 in project KeePassDX by Kunzisoft.
the class PwDbV4Output method outputHeader.
@Override
public PwDbHeader outputHeader(OutputStream os) throws PwDbOutputException {
PwDbHeaderV4 header = new PwDbHeaderV4(mPM);
setIVs(header);
PwDbHeaderOutputV4 pho = new PwDbHeaderOutputV4(mPM, header, os);
try {
pho.output();
} catch (IOException e) {
throw new PwDbOutputException("Failed to output the header.", e);
}
hashOfHeader = pho.getHashOfHeader();
headerHmac = pho.headerHmac;
return header;
}
use of com.keepassdroid.database.PwDbHeaderV4 in project KeePassDX by Kunzisoft.
the class PwDbV4Output method setIVs.
@Override
protected SecureRandom setIVs(PwDbHeader header) throws PwDbOutputException {
SecureRandom random = super.setIVs(header);
PwDbHeaderV4 h = (PwDbHeaderV4) header;
random.nextBytes(h.masterSeed);
int ivLength = engine.ivLength();
if (ivLength != h.encryptionIV.length) {
h.encryptionIV = new byte[ivLength];
}
random.nextBytes(h.encryptionIV);
UUID kdfUUID = mPM.kdfParameters.kdfUUID;
KdfEngine kdf = KdfFactory.get(kdfUUID);
kdf.randomize(mPM.kdfParameters);
if (h.version < PwDbHeaderV4.FILE_VERSION_32_4) {
h.innerRandomStream = CrsAlgorithm.Salsa20;
h.innerRandomStreamKey = new byte[32];
} else {
h.innerRandomStream = CrsAlgorithm.ChaCha20;
h.innerRandomStreamKey = new byte[64];
}
random.nextBytes(h.innerRandomStreamKey);
randomStream = PwStreamCipherFactory.getInstance(h.innerRandomStream, h.innerRandomStreamKey);
if (randomStream == null) {
throw new PwDbOutputException("Invalid random cipher");
}
if (h.version < PwDbHeaderV4.FILE_VERSION_32_4) {
random.nextBytes(h.streamStartBytes);
}
return random;
}
use of com.keepassdroid.database.PwDbHeaderV4 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;
}
Aggregations