Search in sources :

Example 1 with InvalidPasswordException

use of com.keepassdroid.database.exception.InvalidPasswordException in project KeePassDX by Kunzisoft.

the class Database method LoadData.

public void LoadData(Context ctx, Uri uri, String password, Uri keyfile, UpdateStatus status, boolean debug) throws IOException, FileNotFoundException, InvalidDBException {
    mUri = uri;
    readOnly = false;
    if (uri.getScheme().equals("file")) {
        File file = new File(uri.getPath());
        readOnly = !file.canWrite();
    }
    try {
        passUrisAsInputStreams(ctx, uri, password, keyfile, status, debug, 0);
    } catch (InvalidPasswordException e) {
        // Retry with rounds fix
        try {
            passUrisAsInputStreams(ctx, uri, password, keyfile, status, debug, getFixRounds(ctx));
        } catch (Exception e2) {
            // Rethrow original exception
            throw e;
        }
    }
}
Also used : InvalidPasswordException(com.keepassdroid.database.exception.InvalidPasswordException) File(java.io.File) InvalidDBException(com.keepassdroid.database.exception.InvalidDBException) PwDbOutputException(com.keepassdroid.database.exception.PwDbOutputException) InvalidPasswordException(com.keepassdroid.database.exception.InvalidPasswordException) ContentFileNotFoundException(com.keepassdroid.database.exception.ContentFileNotFoundException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) SyncFailedException(java.io.SyncFailedException)

Example 2 with InvalidPasswordException

use of com.keepassdroid.database.exception.InvalidPasswordException in project KeePassDX by Kunzisoft.

the class ImporterV3 method openDatabase.

public PwDatabaseV3 openDatabase(InputStream inStream, String password, InputStream kfIs, UpdateStatus status, long roundsFix) throws IOException, InvalidDBException {
    PwDatabaseV3 newManager;
    // Load entire file, most of it's encrypted.
    int fileSize = inStream.available();
    // Pad with a blocksize (Twofish uses 128 bits), since Android 4.3 tries to write more to the buffer
    byte[] filebuf = new byte[fileSize + 16];
    inStream.read(filebuf, 0, fileSize);
    inStream.close();
    // Parse header (unencrypted)
    if (fileSize < PwDbHeaderV3.BUF_SIZE)
        throw new IOException("File too short for header");
    PwDbHeaderV3 hdr = new PwDbHeaderV3();
    hdr.loadFromFile(filebuf, 0);
    if ((hdr.signature1 != PwDbHeader.PWM_DBSIG_1) || (hdr.signature2 != PwDbHeaderV3.DBSIG_2)) {
        throw new InvalidDBSignatureException();
    }
    if (!hdr.matchesVersion()) {
        throw new InvalidDBVersionException();
    }
    status.updateMessage(R.string.creating_db_key);
    newManager = createDB();
    newManager.setMasterKey(password, kfIs);
    // Select algorithm
    if ((hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0) {
        newManager.algorithm = PwEncryptionAlgorithm.Rjindal;
    } else if ((hdr.flags & PwDbHeaderV3.FLAG_TWOFISH) != 0) {
        newManager.algorithm = PwEncryptionAlgorithm.Twofish;
    } else {
        throw new InvalidAlgorithmException();
    }
    // Copy for testing
    newManager.copyHeader(hdr);
    newManager.numKeyEncRounds = hdr.numKeyEncRounds;
    newManager.name = "KeePass Password Manager";
    // Generate transformedMasterKey from masterKey
    newManager.makeFinalKey(hdr.masterSeed, hdr.transformSeed, newManager.numKeyEncRounds);
    status.updateMessage(R.string.decrypting_db);
    // Initialize Rijndael algorithm
    Cipher cipher;
    try {
        if (newManager.algorithm == PwEncryptionAlgorithm.Rjindal) {
            cipher = CipherFactory.getInstance("AES/CBC/PKCS5Padding");
        } else if (newManager.algorithm == PwEncryptionAlgorithm.Twofish) {
            cipher = CipherFactory.getInstance("Twofish/CBC/PKCS7PADDING");
        } else {
            throw new IOException("Encryption algorithm is not supported");
        }
    } catch (NoSuchAlgorithmException e1) {
        throw new IOException("No such algorithm");
    } catch (NoSuchPaddingException e1) {
        throw new IOException("No such pdading");
    }
    try {
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(newManager.finalKey, "AES"), new IvParameterSpec(hdr.encryptionIV));
    } catch (InvalidKeyException e1) {
        throw new IOException("Invalid key");
    } catch (InvalidAlgorithmParameterException e1) {
        throw new IOException("Invalid algorithm parameter.");
    }
    // Decrypt! The first bytes aren't encrypted (that's the header)
    int encryptedPartSize;
    try {
        encryptedPartSize = cipher.doFinal(filebuf, PwDbHeaderV3.BUF_SIZE, fileSize - PwDbHeaderV3.BUF_SIZE, filebuf, PwDbHeaderV3.BUF_SIZE);
    } catch (ShortBufferException e1) {
        throw new IOException("Buffer too short");
    } catch (IllegalBlockSizeException e1) {
        throw new IOException("Invalid block size");
    } catch (BadPaddingException e1) {
        throw new InvalidPasswordException();
    }
    // Copy decrypted data for testing
    newManager.copyEncrypted(filebuf, PwDbHeaderV3.BUF_SIZE, encryptedPartSize);
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        throw new IOException("No SHA-256 algorithm");
    }
    NullOutputStream nos = new NullOutputStream();
    DigestOutputStream dos = new DigestOutputStream(nos, md);
    dos.write(filebuf, PwDbHeaderV3.BUF_SIZE, encryptedPartSize);
    dos.close();
    byte[] hash = md.digest();
    if (!Arrays.equals(hash, hdr.contentsHash)) {
        Log.w("KeePassDroid", "Database file did not decrypt correctly. (checksum code is broken)");
        throw new InvalidPasswordException();
    }
    // Import all groups
    int pos = PwDbHeaderV3.BUF_SIZE;
    PwGroupV3 newGrp = new PwGroupV3();
    for (int i = 0; i < hdr.numGroups; ) {
        int fieldType = LEDataInputStream.readUShort(filebuf, pos);
        pos += 2;
        int fieldSize = LEDataInputStream.readInt(filebuf, pos);
        pos += 4;
        if (fieldType == 0xFFFF) {
            // End-Group record.  Save group and count it.
            newGrp.populateBlankFields(newManager);
            newManager.groups.add(newGrp);
            newGrp = new PwGroupV3();
            i++;
        } else {
            readGroupField(newManager, newGrp, fieldType, filebuf, pos);
        }
        pos += fieldSize;
    }
    // Import all entries
    PwEntryV3 newEnt = new PwEntryV3();
    for (int i = 0; i < hdr.numEntries; ) {
        int fieldType = LEDataInputStream.readUShort(filebuf, pos);
        int fieldSize = LEDataInputStream.readInt(filebuf, pos + 2);
        if (fieldType == 0xFFFF) {
            // End-Group record.  Save group and count it.
            newEnt.populateBlankFields(newManager);
            newManager.entries.add(newEnt);
            newEnt = new PwEntryV3();
            i++;
        } else {
            readEntryField(newManager, newEnt, filebuf, pos);
        }
        pos += 2 + 4 + fieldSize;
    }
    newManager.constructTree(null);
    return newManager;
}
Also used : PwEntryV3(com.keepassdroid.database.PwEntryV3) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) PwDbHeaderV3(com.keepassdroid.database.PwDbHeaderV3) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) InvalidDBSignatureException(com.keepassdroid.database.exception.InvalidDBSignatureException) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) InvalidKeyException(java.security.InvalidKeyException) InvalidDBVersionException(com.keepassdroid.database.exception.InvalidDBVersionException) PwDatabaseV3(com.keepassdroid.database.PwDatabaseV3) InvalidAlgorithmException(com.keepassdroid.database.exception.InvalidAlgorithmException) PwGroupV3(com.keepassdroid.database.PwGroupV3) SecretKeySpec(javax.crypto.spec.SecretKeySpec) DigestOutputStream(java.security.DigestOutputStream) ShortBufferException(javax.crypto.ShortBufferException) InvalidPasswordException(com.keepassdroid.database.exception.InvalidPasswordException) IvParameterSpec(javax.crypto.spec.IvParameterSpec) Cipher(javax.crypto.Cipher) MessageDigest(java.security.MessageDigest) NullOutputStream(com.keepassdroid.stream.NullOutputStream)

Example 3 with InvalidPasswordException

use of com.keepassdroid.database.exception.InvalidPasswordException in project keepass2android by PhilippC.

the class ImporterV3 method openDatabase.

public PwDatabaseV3 openDatabase(InputStream inStream, String password, InputStream keyfileStream, UpdateStatus status) throws IOException, InvalidDBException {
    PwDatabaseV3 newManager;
    // Load entire file, most of it's encrypted.
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int nRead;
    byte[] data = new byte[16384];
    while ((nRead = inStream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }
    buffer.flush();
    int fileSize = buffer.size();
    // Pad with a blocksize (Twofish uses 128 bits), since Android 4.3 tries to write more to the buffer
    for (int i = 0; i < 16; i++) {
        buffer.write(0);
    }
    inStream.close();
    byte[] filebuf = buffer.toByteArray();
    // Parse header (unencrypted)
    if (fileSize < PwDbHeaderV3.BUF_SIZE)
        throw new IOException("File too short for header: " + fileSize + "<" + PwDbHeaderV3.BUF_SIZE);
    PwDbHeaderV3 hdr = new PwDbHeaderV3();
    hdr.loadFromFile(filebuf, 0);
    if ((hdr.signature1 != PwDbHeader.PWM_DBSIG_1) || (hdr.signature2 != PwDbHeaderV3.DBSIG_2)) {
        throw new InvalidDBSignatureException();
    }
    if (!hdr.matchesVersion()) {
        throw new InvalidDBVersionException();
    }
    newManager = createDB();
    newManager.setMasterKey(password, keyfileStream);
    // Select algorithm
    if ((hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0) {
        newManager.algorithm = PwEncryptionAlgorithm.Rjindal;
    } else if ((hdr.flags & PwDbHeaderV3.FLAG_TWOFISH) != 0) {
        newManager.algorithm = PwEncryptionAlgorithm.Twofish;
    } else {
        throw new InvalidAlgorithmException();
    }
    // Copy for testing
    newManager.copyHeader(hdr);
    newManager.numKeyEncRounds = hdr.numKeyEncRounds;
    newManager.name = "KeePass Password Manager";
    // Generate transformedMasterKey from masterKey
    newManager.makeFinalKey(hdr.masterSeed, hdr.transformSeed, newManager.numKeyEncRounds);
    // Initialize Rijndael algorithm
    Cipher cipher;
    try {
        if (newManager.algorithm == PwEncryptionAlgorithm.Rjindal) {
            cipher = CipherFactory.getInstance("AES/CBC/PKCS5Padding");
        } else if (newManager.algorithm == PwEncryptionAlgorithm.Twofish) {
            cipher = CipherFactory.getInstance("TWOFISH/CBC/PKCS7PADDING");
        } else {
            throw new IOException("Encryption algorithm is not supported");
        }
    } catch (NoSuchAlgorithmException e1) {
        throw new IOException("No such algorithm");
    } catch (NoSuchPaddingException e1) {
        throw new IOException("No such pdading");
    }
    try {
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(newManager.finalKey, "AES"), new IvParameterSpec(hdr.encryptionIV));
    } catch (InvalidKeyException e1) {
        throw new IOException("Invalid key");
    } catch (InvalidAlgorithmParameterException e1) {
        throw new IOException("Invalid algorithm parameter.");
    }
    // Decrypt! The first bytes aren't encrypted (that's the header)
    int encryptedPartSize;
    try {
        encryptedPartSize = cipher.doFinal(filebuf, PwDbHeaderV3.BUF_SIZE, fileSize - PwDbHeaderV3.BUF_SIZE, filebuf, PwDbHeaderV3.BUF_SIZE);
    } catch (ShortBufferException e1) {
        throw new IOException("Buffer too short");
    } catch (IllegalBlockSizeException e1) {
        throw new IOException("Invalid block size");
    } catch (BadPaddingException e1) {
        throw new InvalidPasswordException("Invalid key!");
    }
    // Copy decrypted data for testing
    newManager.copyEncrypted(filebuf, PwDbHeaderV3.BUF_SIZE, encryptedPartSize);
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        throw new IOException("No SHA-256 algorithm");
    }
    NullOutputStream nos = new NullOutputStream();
    DigestOutputStream dos = new DigestOutputStream(nos, md);
    dos.write(filebuf, PwDbHeaderV3.BUF_SIZE, encryptedPartSize);
    dos.close();
    byte[] hash = md.digest();
    if (!Arrays.equals(hash, hdr.contentsHash)) {
        Log.w("KeePassDroid", "Database file did not decrypt correctly. (checksum code is broken)");
        throw new InvalidPasswordException("Invalid key!");
    }
    // Import all groups
    int pos = PwDbHeaderV3.BUF_SIZE;
    PwGroupV3 newGrp = new PwGroupV3();
    for (int i = 0; i < hdr.numGroups; ) {
        int fieldType = LEDataInputStream.readUShort(filebuf, pos);
        pos += 2;
        int fieldSize = LEDataInputStream.readInt(filebuf, pos);
        pos += 4;
        if (fieldType == 0xFFFF) {
            // End-Group record.  Save group and count it.
            newGrp.populateBlankFields(newManager);
            newManager.groups.add(newGrp);
            newGrp = new PwGroupV3();
            i++;
        } else {
            readGroupField(newManager, newGrp, fieldType, filebuf, pos);
        }
        pos += fieldSize;
    }
    // Import all entries
    PwEntryV3 newEnt = new PwEntryV3();
    for (int i = 0; i < hdr.numEntries; ) {
        int fieldType = LEDataInputStream.readUShort(filebuf, pos);
        int fieldSize = LEDataInputStream.readInt(filebuf, pos + 2);
        if (fieldType == 0xFFFF) {
            // End-Group record.  Save group and count it.
            newEnt.populateBlankFields(newManager);
            newManager.entries.add(newEnt);
            newEnt = new PwEntryV3();
            i++;
        } else {
            readEntryField(newManager, newEnt, filebuf, pos);
        }
        pos += 2 + 4 + fieldSize;
    }
    newManager.constructTree(null);
    return newManager;
}
Also used : PwEntryV3(com.keepassdroid.database.PwEntryV3) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) InvalidDBSignatureException(com.keepassdroid.database.exception.InvalidDBSignatureException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) InvalidDBVersionException(com.keepassdroid.database.exception.InvalidDBVersionException) PwDatabaseV3(com.keepassdroid.database.PwDatabaseV3) SecretKeySpec(javax.crypto.spec.SecretKeySpec) DigestOutputStream(java.security.DigestOutputStream) InvalidPasswordException(com.keepassdroid.database.exception.InvalidPasswordException) MessageDigest(java.security.MessageDigest) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) PwDbHeaderV3(com.keepassdroid.database.PwDbHeaderV3) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) InvalidAlgorithmException(com.keepassdroid.database.exception.InvalidAlgorithmException) PwGroupV3(com.keepassdroid.database.PwGroupV3) ShortBufferException(javax.crypto.ShortBufferException) IvParameterSpec(javax.crypto.spec.IvParameterSpec) Cipher(javax.crypto.Cipher) NullOutputStream(com.keepassdroid.stream.NullOutputStream)

Example 4 with InvalidPasswordException

use of com.keepassdroid.database.exception.InvalidPasswordException 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;
}
Also used : InvalidDBException(com.keepassdroid.database.exception.InvalidDBException) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) GZIPInputStream(java.util.zip.GZIPInputStream) HashedBlockInputStream(com.keepassdroid.stream.HashedBlockInputStream) LEDataInputStream(com.keepassdroid.stream.LEDataInputStream) BetterCipherInputStream(com.keepassdroid.stream.BetterCipherInputStream) HmacBlockInputStream(com.keepassdroid.stream.HmacBlockInputStream) InputStream(java.io.InputStream) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) LEDataInputStream(com.keepassdroid.stream.LEDataInputStream) ArcFourException(com.keepassdroid.database.exception.ArcFourException) GZIPInputStream(java.util.zip.GZIPInputStream) HmacBlockInputStream(com.keepassdroid.stream.HmacBlockInputStream) PwDbHeaderV4(com.keepassdroid.database.PwDbHeaderV4) CipherEngine(com.keepassdroid.crypto.engine.CipherEngine) InvalidPasswordException(com.keepassdroid.database.exception.InvalidPasswordException) StreamCipher(org.spongycastle.crypto.StreamCipher) Cipher(javax.crypto.Cipher) HashedBlockInputStream(com.keepassdroid.stream.HashedBlockInputStream)

Aggregations

InvalidPasswordException (com.keepassdroid.database.exception.InvalidPasswordException)4 IOException (java.io.IOException)4 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)3 InvalidKeyException (java.security.InvalidKeyException)3 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 Cipher (javax.crypto.Cipher)3 NoSuchPaddingException (javax.crypto.NoSuchPaddingException)3 PwDatabaseV3 (com.keepassdroid.database.PwDatabaseV3)2 PwDbHeaderV3 (com.keepassdroid.database.PwDbHeaderV3)2 PwEntryV3 (com.keepassdroid.database.PwEntryV3)2 PwGroupV3 (com.keepassdroid.database.PwGroupV3)2 InvalidAlgorithmException (com.keepassdroid.database.exception.InvalidAlgorithmException)2 InvalidDBException (com.keepassdroid.database.exception.InvalidDBException)2 InvalidDBSignatureException (com.keepassdroid.database.exception.InvalidDBSignatureException)2 InvalidDBVersionException (com.keepassdroid.database.exception.InvalidDBVersionException)2 NullOutputStream (com.keepassdroid.stream.NullOutputStream)2 DigestOutputStream (java.security.DigestOutputStream)2 MessageDigest (java.security.MessageDigest)2 BadPaddingException (javax.crypto.BadPaddingException)2 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)2