@Test public void generateVerityTreeRootHashFromDummyDataSource() throws Exception { byte[] sampleEoCDFromDisk = new byte[] { 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x79, 0x01, 0x00, 0x00, 0x30, 0x16, 0x00, 0x00, 0x00, 0x00 }; String expectedRootHash = "7694e72c242107a5b4ce6091faf867e2f13c033b6b64faddcb13b3d698a8495a"; { VerityTreeBuilder builder = new VerityTreeBuilder(null); byte[] rootHash = builder.generateVerityTreeRootHash( DataSources.asDataSource(ByteBuffer.allocate(4096)), makeStringDataSource("this is central directory (fake data)"), DataSources.asDataSource(ByteBuffer.wrap(sampleEoCDFromDisk))); assertEquals(expectedRootHash, HexEncoding.encode(rootHash)); } { ByteBuffer fileTailWithDifferentLengthOfZeros = ByteBuffer.allocate( sampleEoCDFromDisk.length + 1); fileTailWithDifferentLengthOfZeros.put(sampleEoCDFromDisk); fileTailWithDifferentLengthOfZeros.rewind(); VerityTreeBuilder builder = new VerityTreeBuilder(null); byte[] rootHash = builder.generateVerityTreeRootHash( DataSources.asDataSource(ByteBuffer.allocate(4096)), makeStringDataSource("this is central directory (fake data)"), DataSources.asDataSource(fileTailWithDifferentLengthOfZeros)); assertEquals(expectedRootHash, HexEncoding.encode(rootHash)); } }
public byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock, DataSource centralDir, DataSource eocd) throws IOException { if (beforeApkSigningBlock.size() % CHUNK_SIZE != 0) { throw new IllegalStateException("APK Signing Block size not a multiple of " + CHUNK_SIZE + ": " + beforeApkSigningBlock.size()); } long centralDirOffsetForDigesting = beforeApkSigningBlock.size(); ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size()); eocdBuf.order(ByteOrder.LITTLE_ENDIAN); eocd.copyTo(0, (int) eocd.size(), eocdBuf); eocdBuf.flip(); ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting); return generateVerityTreeRootHash(new ChainedDataSource(beforeApkSigningBlock, centralDir, DataSources.asDataSource(eocdBuf))); }
VerityTreeBuilder { public byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock, DataSource centralDir, DataSource eocd) throws IOException { if (beforeApkSigningBlock.size() % CHUNK_SIZE != 0) { throw new IllegalStateException("APK Signing Block size not a multiple of " + CHUNK_SIZE + ": " + beforeApkSigningBlock.size()); } long centralDirOffsetForDigesting = beforeApkSigningBlock.size(); ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size()); eocdBuf.order(ByteOrder.LITTLE_ENDIAN); eocd.copyTo(0, (int) eocd.size(), eocdBuf); eocdBuf.flip(); ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting); return generateVerityTreeRootHash(new ChainedDataSource(beforeApkSigningBlock, centralDir, DataSources.asDataSource(eocdBuf))); } }
VerityTreeBuilder { public byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock, DataSource centralDir, DataSource eocd) throws IOException { if (beforeApkSigningBlock.size() % CHUNK_SIZE != 0) { throw new IllegalStateException("APK Signing Block size not a multiple of " + CHUNK_SIZE + ": " + beforeApkSigningBlock.size()); } long centralDirOffsetForDigesting = beforeApkSigningBlock.size(); ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size()); eocdBuf.order(ByteOrder.LITTLE_ENDIAN); eocd.copyTo(0, (int) eocd.size(), eocdBuf); eocdBuf.flip(); ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting); return generateVerityTreeRootHash(new ChainedDataSource(beforeApkSigningBlock, centralDir, DataSources.asDataSource(eocdBuf))); } VerityTreeBuilder(byte[] salt); }
VerityTreeBuilder { public byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock, DataSource centralDir, DataSource eocd) throws IOException { if (beforeApkSigningBlock.size() % CHUNK_SIZE != 0) { throw new IllegalStateException("APK Signing Block size not a multiple of " + CHUNK_SIZE + ": " + beforeApkSigningBlock.size()); } long centralDirOffsetForDigesting = beforeApkSigningBlock.size(); ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size()); eocdBuf.order(ByteOrder.LITTLE_ENDIAN); eocd.copyTo(0, (int) eocd.size(), eocdBuf); eocdBuf.flip(); ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting); return generateVerityTreeRootHash(new ChainedDataSource(beforeApkSigningBlock, centralDir, DataSources.asDataSource(eocdBuf))); } VerityTreeBuilder(byte[] salt); byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock,
            DataSource centralDir, DataSource eocd); }
VerityTreeBuilder { public byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock, DataSource centralDir, DataSource eocd) throws IOException { if (beforeApkSigningBlock.size() % CHUNK_SIZE != 0) { throw new IllegalStateException("APK Signing Block size not a multiple of " + CHUNK_SIZE + ": " + beforeApkSigningBlock.size()); } long centralDirOffsetForDigesting = beforeApkSigningBlock.size(); ByteBuffer eocdBuf = ByteBuffer.allocate((int) eocd.size()); eocdBuf.order(ByteOrder.LITTLE_ENDIAN); eocd.copyTo(0, (int) eocd.size(), eocdBuf); eocdBuf.flip(); ZipUtils.setZipEocdCentralDirectoryOffset(eocdBuf, centralDirOffsetForDigesting); return generateVerityTreeRootHash(new ChainedDataSource(beforeApkSigningBlock, centralDir, DataSources.asDataSource(eocdBuf))); } VerityTreeBuilder(byte[] salt); byte[] generateVerityTreeRootHash(DataSource beforeApkSigningBlock,
            DataSource centralDir, DataSource eocd);  }