Esempio n. 1
0
  @Override
  public PwDatabaseV4 openDatabase(
      InputStream inStream, String password, String keyfile, UpdateStatus status)
      throws IOException, InvalidDBException {

    db = createDB();

    PwDbHeaderV4 header = new PwDbHeaderV4(db);

    hashOfHeader = header.loadFromFile(inStream);

    db.setMasterKey(password, keyfile);
    db.makeFinalKey(header.masterSeed, header.transformSeed, (int) db.numKeyEncRounds);

    // Attach decryptor
    Cipher cipher;
    try {
      cipher =
          CipherFactory.getInstance(
              db.dataCipher, 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 decrypted = new BetterCipherInputStream(inStream, cipher, 50 * 1024);
    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();
    }

    HashedBlockInputStream hashed = new HashedBlockInputStream(dataDecrypted);

    InputStream decompressed;
    if (db.compressionAlgorithm == PwCompressionAlgorithm.Gzip) {
      decompressed = new GZIPInputStream(hashed);
    } else {
      decompressed = hashed;
    }

    if (header.protectedStreamKey == null) {
      assert (false);
      throw new IOException("Invalid stream key.");
    }

    randomStream =
        PwStreamCipherFactory.getInstance(header.innerRandomStream, header.protectedStreamKey);

    if (randomStream == null) {
      throw new ArcFourException();
    }

    ReadXmlStreamed(decompressed);

    return db;
  }