package org.mp4parser.muxer.samples; import org.junit.Assert; import org.junit.Test; import org.mp4parser.boxes.iso23001.part7.CencSampleAuxiliaryDataFormat; import org.mp4parser.muxer.Sample; import org.mp4parser.muxer.SampleImpl; import org.mp4parser.tools.Hex; import org.mp4parser.tools.RangeStartMap; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * Created by sannies on 1/9/14. */ public class CencSampleListsTest { String encryptedWorking = "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000DBF184112EB9111659712BAFCFF2AB249A7A06" + "19AAC29E6C1F2B5C4753D588F3142C51C9AF2CF1D92E8937C4FBC18D7AB212DA6951717F955907CA" + "D6BCFE086AB884CCFD8FB15E9915DB6AD76B296E4DF75D95D7A723B9FD967BF470B20130B8E0F59B" + "A30B8F5952638DE780179C95ABCA7A3453984B8BAB49189FA1A1FB5996872A681256DF43A616C790" + "BEF3041122FDF86ACAF3000127D77692B8DD6B44CB6AEEC7D3920932F607A3445CC03A6101E6648B" + "E4CF350EC5B1C195B4431779A2AF1877AD1499EE2611D3C8BB48172DCF7367F9F8F40E49AECE2DA7" + "44430E6757C6517D4198A9AB74CD0409CD4B8AAA1B98C2DF4A0EA02FCB6383FF34D84F10373CE3B1" + "DF6B0D29D1DB0154A3CB05E4D962BB636C1F65181B28CA5B831481E910E8D478497B459A4B940087" + "6115BDBDF99A20D799E372977105566FF2818AD6CF03253B42C7961C26A85A6180EAC0736C5A1F0F" + "2EC9833180FD82F14B63903F8AB8D006BD91E762AD5117DA4ECC33328E78373E3AC7913A11569983" + "E31F75D2A70000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000012C39E2DB870BD84029C" + "C00D3C123C53CFE967DED22459B413C8784D746C36E06B8C1EA14193C9B7A3652F6168D321939955" + "B86816E30E8C3D6CE8980D4E2FB4738CA7A21E14CF08D9E9723A59AF03B2961F8001B4409B66432D" + "1DD2BADE4BF4B50392645B6E2BE2FE93A6FD65D18AE60024CBFF010543C2D2E907812FE319A7CA5D" + "F6198A830FCB2E09D4D94638E909B0AEA344C6E5EE0C22546CDE272B54332BA83010BC570C738F82" + "78DFC4B63FDDAC2FB138ADF70C54606709E2B1035EE961DAF730F099EFA92D5AE4A87386DD54C1DC" + "919FE0E3D19C0D591EF9FEE498296D7DD967FE6112FCADABCB54D8F6AFF57C5BF9B032E8F790AD5A" + "A25EB003AC143E32E49A6D2D9D40990377A5E7EF76EC00F8D08B48333568505B6DA69B96CDBF7A7E" + "70886235FECC83389FC6EEAED3ECEFE4CB941A85C8D5B50A57A0BEB6A62918769ECAB79F9717741D" + "0118933E0611DEED910FE7ADD8B95355A9D4C43CD9328A3C585F5973BF16586FB4CFE0F419D56BC0" + "0C0BEAE83933ACB83E1DF2DC1B3E14FD5E5352E46EB823C33CF674D6292AAB377520EF22C60D60B1" + "7BB73DE3CD78215A52D3EDBDAD96D2B62F953CFF333AE9C221CDD9B498A03F886F761CBBC0C954B7" + "A57CFD0181094CFF0F5EBAC1056CF6DC0406D26BF612E2EE748CA2B52863889C81DD4D5419B009A6" + "6927B591060A0A4275044F03857138E4F761F1B58B980337BEF2957F1FF2E9B1351D517FB93F01C3" + "215EA09090A23EC3BFFC12F48E92101F6FE95C3C117998BA360050448B2753D0584A41F18EA25BCD" + "BDAA10DB623FBB53D3DB6F7D028990B411B9B5ECB11F423A9D2A4F8AFFC51E8B0C471545B4A545A7" + "0C7D89D42F0DC946A43389A6BF0168F546AC1667F43937DC4893DB329249"; @Test public void test() throws IOException { SecretKey secretKey = new SecretKeySpec(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, "AES"); List<Sample> clearSamples = Collections.<Sample>singletonList( new SampleImpl(ByteBuffer.wrap(new byte[1230]))); CencSampleAuxiliaryDataFormat cencSampleAuxiliaryDataFormat = new CencSampleAuxiliaryDataFormat(); cencSampleAuxiliaryDataFormat.pairs = new CencSampleAuxiliaryDataFormat.Pair[2]; cencSampleAuxiliaryDataFormat.pairs[0] = cencSampleAuxiliaryDataFormat.createPair(101, 384); cencSampleAuxiliaryDataFormat.pairs[1] = cencSampleAuxiliaryDataFormat.createPair(105, 640); cencSampleAuxiliaryDataFormat.iv = new byte[16]; CencEncryptingSampleList cencSamples = new CencEncryptingSampleList( secretKey, clearSamples, Collections.singletonList(cencSampleAuxiliaryDataFormat)); Assert.assertEquals(1, cencSamples.size()); Sample encSample = cencSamples.get(0); ByteArrayOutputStream baos = new ByteArrayOutputStream(); encSample.writeTo(Channels.newChannel(baos)); Assert.assertEquals(encryptedWorking, Hex.encodeHex(baos.toByteArray())); Assert.assertEquals(encryptedWorking, Hex.encodeHex(encSample.asByteBuffer().array())); } @Test public void testMultipleKeysCencSubSample() throws IOException { testMultipleKeys("cenc", true); } @Test public void testMultipleKeysCbc1SubSample() throws IOException { testMultipleKeys("cbc1", true); } @Test public void testMultipleKeysCencFull() throws IOException { testMultipleKeys("cenc", false); } @Test public void testMultipleKeysCbc1Full() throws IOException { testMultipleKeys("cbc1", false); } public void testMultipleKeys(String encAlgo, boolean subSampleEncryption) throws IOException { SecretKey cek1 = new SecretKeySpec(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, "AES"); SecretKey cek2 = new SecretKeySpec(new byte[]{2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, "AES"); RangeStartMap<Integer, SecretKey> keys = new RangeStartMap<Integer, SecretKey>(); keys.put(0, cek1); keys.put(3, null); keys.put(5, cek2); List<Sample> clearSamples = Arrays.<Sample>asList( new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])), new SampleImpl(ByteBuffer.wrap(new byte[1230])) ); CencSampleAuxiliaryDataFormat cencAuxDef = new CencSampleAuxiliaryDataFormat(); if (subSampleEncryption) { cencAuxDef.pairs = new CencSampleAuxiliaryDataFormat.Pair[2]; cencAuxDef.pairs[0] = cencAuxDef.createPair(101, 384); cencAuxDef.pairs[1] = cencAuxDef.createPair(105, 640); } cencAuxDef.iv = new byte[16]; CencSampleAuxiliaryDataFormat cencAuxPlain = new CencSampleAuxiliaryDataFormat(); List<CencSampleAuxiliaryDataFormat> auxInfos = Arrays.asList( cencAuxDef, cencAuxDef, cencAuxDef, cencAuxPlain, cencAuxPlain, cencAuxDef, cencAuxDef, cencAuxDef, cencAuxDef); CencEncryptingSampleList cencSamples = new CencEncryptingSampleList( keys, clearSamples, auxInfos, encAlgo); Assert.assertEquals(9, cencSamples.size()); for (int i = 0; i < cencSamples.size(); i++) { CencDecryptingSampleList dec = new CencDecryptingSampleList( new RangeStartMap<Integer, SecretKey>(0, keys.get(i)), Collections.singletonList(cencSamples.get(i)), Collections.singletonList(auxInfos.get(i)), encAlgo); ByteArrayOutputStream baos = new ByteArrayOutputStream(); dec.get(0).writeTo(Channels.newChannel(baos)); Assert.assertArrayEquals("Sample " + i + " can not be reconstructed", new byte[1230], baos.toByteArray()); } CencDecryptingSampleList decryptingSampleList = new CencDecryptingSampleList( keys, cencSamples, auxInfos, encAlgo); for (int i = 0; i < cencSamples.size(); i++) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); decryptingSampleList.get(i).writeTo(Channels.newChannel(baos)); Assert.assertArrayEquals("Sample " + i + " can not be reconstructed", new byte[1230], baos.toByteArray()); } } }