Example #1
0
  /**
   * Create a new EncFSInputStream for reading decrypted data off a file on an EncFS volume
   *
   * @param volume Volume hosting the file to read
   * @param in Input stream to access the raw (encrypted) file contents
   * @param volumePath Volume path of the file being decrypted (needed for externalIVChaining)
   * @throws EncFSCorruptDataException File data is corrupt
   * @throws EncFSUnsupportedException Unsupported EncFS configuration
   * @throws IOException File provider returned I/O error
   */
  public EncFSInputStream(EncFSVolume volume, InputStream in, String volumePath)
      throws EncFSCorruptDataException, EncFSUnsupportedException {
    super(in);
    this.volume = volume;
    this.config = volume.getConfig();
    this.blockSize = config.getBlockSize();
    this.numMACBytes = config.getBlockMACBytes();
    this.numRandBytes = config.getBlockMACRandBytes();
    this.blockHeaderSize = this.numMACBytes + this.numRandBytes;
    this.blockBuf = null;
    this.bufCursor = 0;
    this.blockNum = 0;

    if (config.isUniqueIV()) {
      // Compute file IV
      byte[] fileHeader = new byte[EncFSFile.HEADER_SIZE];
      try {
        in.read(fileHeader);
      } catch (IOException e) {
        throw new EncFSCorruptDataException("Could't read file IV");
      }

      byte[] initIv;
      if (config.isExternalIVChaining()) {
        /*
         * When using external IV chaining we compute initIv based on
         * the file path.
         */
        initIv = EncFSCrypto.computeChainIv(volume, volumePath);
      } else {
        // When not using external IV chaining initIv is just zero's.
        initIv = new byte[8];
      }

      try {
        this.fileIv = EncFSCrypto.streamDecode(volume, initIv, fileHeader);
      } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
      } catch (IllegalBlockSizeException e) {
        throw new EncFSCorruptDataException(e);
      } catch (BadPaddingException e) {
        throw new EncFSCorruptDataException(e);
      }
    } else {
      // No unique IV per file, just use 0
      this.fileIv = new byte[EncFSFile.HEADER_SIZE];
    }
  }