97d703e4 by David LaPalomento

Merge pull request #540 from BrandonOCasey/browserify-p3

browserify-p3: decrypter
2 parents a8daa7f7 1011b09b
...@@ -47,13 +47,11 @@ ...@@ -47,13 +47,11 @@
47 47
48 <script src="/node_modules/video.js/dist/video.js"></script> 48 <script src="/node_modules/video.js/dist/video.js"></script>
49 <script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script> 49 <script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
50 <script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
51 <script src="/src/videojs-contrib-hls.js"></script> 50 <script src="/src/videojs-contrib-hls.js"></script>
52 <script src="/src/xhr.js"></script> 51 <script src="/src/xhr.js"></script>
53 <script src="/dist/videojs-contrib-hls.js"></script> 52 <script src="/dist/videojs-contrib-hls.js"></script>
54 <script src="/src/playlist.js"></script> 53 <script src="/src/playlist.js"></script>
55 <script src="/src/playlist-loader.js"></script> 54 <script src="/src/playlist-loader.js"></script>
56 <script src="/src/decrypter.js"></script>
57 <script src="/src/bin-utils.js"></script> 55 <script src="/src/bin-utils.js"></script>
58 <script> 56 <script>
59 (function(window, videojs) { 57 (function(window, videojs) {
......
...@@ -2,7 +2,7 @@ var browserify = require('browserify'); ...@@ -2,7 +2,7 @@ var browserify = require('browserify');
2 var fs = require('fs'); 2 var fs = require('fs');
3 var glob = require('glob'); 3 var glob = require('glob');
4 4
5 glob('test/{m3u8,stub}.test.js', function(err, files) { 5 glob('test/{decryper,m3u8,stub}.test.js', function(err, files) {
6 browserify(files) 6 browserify(files)
7 .transform('babelify') 7 .transform('babelify')
8 .bundle() 8 .bundle()
......
...@@ -3,7 +3,7 @@ var fs = require('fs'); ...@@ -3,7 +3,7 @@ var fs = require('fs');
3 var glob = require('glob'); 3 var glob = require('glob');
4 var watchify = require('watchify'); 4 var watchify = require('watchify');
5 5
6 glob('test/{m3u8,stub}.test.js', function(err, files) { 6 glob('test/{decrypter,m3u8,stub}.test.js', function(err, files) {
7 var b = browserify(files, { 7 var b = browserify(files, {
8 cache: {}, 8 cache: {},
9 packageCache: {}, 9 packageCache: {},
......
1 import m3u8 from './m3u8'; 1 import m3u8 from './m3u8';
2 import Stream from './stream'; 2 import Stream from './stream';
3 import videojs from 'video.js'; 3 import videojs from 'video.js';
4 import {Decrypter, decrypt, AsyncStream} from './decrypter';
4 5
5 if(typeof window.videojs.Hls === 'undefined') { 6 if(typeof window.videojs.Hls === 'undefined') {
6 videojs.Hls = {}; 7 videojs.Hls = {};
7 } 8 }
8 videojs.Hls.Stream = Stream; 9 videojs.Hls.Stream = Stream;
9 videojs.m3u8 = m3u8; 10 videojs.m3u8 = m3u8;
10 11 videojs.Hls.decrypt = decrypt;
12 videojs.Hls.Decrypter = Decrypter;
13 videojs.Hls.AsyncStream = AsyncStream;
......
1 (function(window, videojs, unpad, undefined) {
2 'use strict';
3 /*
4 ======== A Handy Little QUnit Reference ========
5 http://api.qunitjs.com/
6
7 Test methods:
8 module(name, {[setup][ ,teardown]})
9 test(name, callback)
10 expect(numberOfAssertions)
11 stop(increment)
12 start(decrement)
13 Test assertions:
14 ok(value, [message])
15 equal(actual, expected, [message])
16 notEqual(actual, expected, [message])
17 deepEqual(actual, expected, [message])
18 notDeepEqual(actual, expected, [message])
19 strictEqual(actual, expected, [message])
20 notStrictEqual(actual, expected, [message])
21 throws(block, [expected], [message])
22 */
23
24 // see docs/hlse.md for instructions on how test data was generated 1 // see docs/hlse.md for instructions on how test data was generated
2 import QUnit from 'qunit';
3 import {unpad} from 'pkcs7';
4 import sinon from 'sinon';
5 import {decrypt, Decrypter, AsyncStream} from '../src/decrypter';
25 6
26 var stringFromBytes = function(bytes) { 7 // see docs/hlse.md for instructions on how test data was generated
27 var result = '', i; 8 const stringFromBytes = function(bytes) {
9 let result = '';
28 10
29 for (i = 0; i < bytes.length; i++) { 11 for (let i = 0; i < bytes.length; i++) {
30 result += String.fromCharCode(bytes[i]); 12 result += String.fromCharCode(bytes[i]);
31 } 13 }
32 return result; 14 return result;
33 }; 15 };
34 16
35 QUnit.module('Decryption'); 17 QUnit.module('Decryption');
36 18 QUnit.test('decrypts a single AES-128 with PKCS7 block', function() {
37 test('decrypts a single AES-128 with PKCS7 block', function() { 19 let key = new Uint32Array([0, 0, 0, 0]);
38 var 20 let initVector = key;
39 key = new Uint32Array([0, 0, 0, 0]),
40 initVector = key,
41 // the string "howdy folks" encrypted 21 // the string "howdy folks" encrypted
42 encrypted = new Uint8Array([ 22 let encrypted = new Uint8Array([
43 0xce, 0x90, 0x97, 0xd0, 23 0xce, 0x90, 0x97, 0xd0,
44 0x08, 0x46, 0x4d, 0x18, 24 0x08, 0x46, 0x4d, 0x18,
45 0x4f, 0xae, 0x01, 0x1c, 25 0x4f, 0xae, 0x01, 0x1c,
46 0x82, 0xa8, 0xf0, 0x67]); 26 0x82, 0xa8, 0xf0, 0x67
27 ]);
47 28
48 deepEqual('howdy folks', 29 QUnit.deepEqual('howdy folks',
49 stringFromBytes(unpad(videojs.Hls.decrypt(encrypted, key, initVector))), 30 stringFromBytes(unpad(decrypt(encrypted, key, initVector))),
50 'decrypted with a byte array key'); 31 'decrypted with a byte array key'
32 );
51 }); 33 });
52 34
53 test('decrypts multiple AES-128 blocks with CBC', function() { 35 QUnit.test('decrypts multiple AES-128 blocks with CBC', function() {
54 var 36 let key = new Uint32Array([0, 0, 0, 0]);
55 key = new Uint32Array([0, 0, 0, 0]), 37 let initVector = key;
56 initVector = key,
57 // the string "0123456789abcdef01234" encrypted 38 // the string "0123456789abcdef01234" encrypted
58 encrypted = new Uint8Array([ 39 let encrypted = new Uint8Array([
40 0x14, 0xf5, 0xfe, 0x74,
41 0x69, 0x66, 0xf2, 0x92,
42 0x65, 0x1c, 0x22, 0x88,
43 0xbb, 0xff, 0x46, 0x09,
44
45 0x0b, 0xde, 0x5e, 0x71,
46 0x77, 0x87, 0xeb, 0x84,
47 0xa9, 0x54, 0xc2, 0x45,
48 0xe9, 0x4e, 0x29, 0xb3
49 ]);
50
51 QUnit.deepEqual('0123456789abcdef01234',
52 stringFromBytes(unpad(decrypt(encrypted, key, initVector))),
53 'decrypted multiple blocks');
54 });
55
56 QUnit.test(
57 'verify that the deepcopy works by doing two decrypts in the same test',
58 function() {
59 let key = new Uint32Array([0, 0, 0, 0]);
60 let initVector = key;
61 // the string "howdy folks" encrypted
62 let pkcs7Block = new Uint8Array([
63 0xce, 0x90, 0x97, 0xd0,
64 0x08, 0x46, 0x4d, 0x18,
65 0x4f, 0xae, 0x01, 0x1c,
66 0x82, 0xa8, 0xf0, 0x67
67 ]);
68
69 QUnit.deepEqual('howdy folks',
70 stringFromBytes(unpad(decrypt(pkcs7Block, key, initVector))),
71 'decrypted with a byte array key'
72 );
73
74 // the string "0123456789abcdef01234" encrypted
75 let cbcBlocks = new Uint8Array([
59 0x14, 0xf5, 0xfe, 0x74, 76 0x14, 0xf5, 0xfe, 0x74,
60 0x69, 0x66, 0xf2, 0x92, 77 0x69, 0x66, 0xf2, 0x92,
61 0x65, 0x1c, 0x22, 0x88, 78 0x65, 0x1c, 0x22, 0x88,
...@@ -67,38 +84,40 @@ test('decrypts multiple AES-128 blocks with CBC', function() { ...@@ -67,38 +84,40 @@ test('decrypts multiple AES-128 blocks with CBC', function() {
67 0xe9, 0x4e, 0x29, 0xb3 84 0xe9, 0x4e, 0x29, 0xb3
68 ]); 85 ]);
69 86
70 deepEqual('0123456789abcdef01234', 87 QUnit.deepEqual('0123456789abcdef01234',
71 stringFromBytes(unpad(videojs.Hls.decrypt(encrypted, key, initVector))), 88 stringFromBytes(unpad(decrypt(cbcBlocks, key, initVector))),
72 'decrypted multiple blocks'); 89 'decrypted multiple blocks');
90
73 }); 91 });
74 92
75 var clock;
76 93
77 QUnit.module('Incremental Processing', { 94 QUnit.module('Incremental Processing', {
78 setup: function() { 95 beforeEach() {
79 clock = sinon.useFakeTimers(); 96 this.clock = sinon.useFakeTimers();
80 }, 97 },
81 teardown: function() { 98 afterEach() {
82 clock.restore(); 99 this.clock.restore();
83 } 100 }
84 }); 101 });
85 102
86 test('executes a callback after a timeout', function() { 103 QUnit.test('executes a callback after a timeout', function() {
87 var asyncStream = new videojs.Hls.AsyncStream(), 104 let asyncStream = new AsyncStream();
88 calls = ''; 105 let calls = '';
106
89 asyncStream.push(function() { 107 asyncStream.push(function() {
90 calls += 'a'; 108 calls += 'a';
91 }); 109 });
92 110
93 clock.tick(asyncStream.delay); 111 this.clock.tick(asyncStream.delay);
94 equal(calls, 'a', 'invoked the callback once'); 112 QUnit.equal(calls, 'a', 'invoked the callback once');
95 clock.tick(asyncStream.delay); 113 this.clock.tick(asyncStream.delay);
96 equal(calls, 'a', 'only invoked the callback once'); 114 QUnit.equal(calls, 'a', 'only invoked the callback once');
97 }); 115 });
98 116
99 test('executes callback in series', function() { 117 QUnit.test('executes callback in series', function() {
100 var asyncStream = new videojs.Hls.AsyncStream(), 118 let asyncStream = new AsyncStream();
101 calls = ''; 119 let calls = '';
120
102 asyncStream.push(function() { 121 asyncStream.push(function() {
103 calls += 'a'; 122 calls += 'a';
104 }); 123 });
...@@ -106,62 +125,62 @@ test('executes callback in series', function() { ...@@ -106,62 +125,62 @@ test('executes callback in series', function() {
106 calls += 'b'; 125 calls += 'b';
107 }); 126 });
108 127
109 clock.tick(asyncStream.delay); 128 this.clock.tick(asyncStream.delay);
110 equal(calls, 'a', 'invoked the first callback'); 129 QUnit.equal(calls, 'a', 'invoked the first callback');
111 clock.tick(asyncStream.delay); 130 this.clock.tick(asyncStream.delay);
112 equal(calls, 'ab', 'invoked the second'); 131 QUnit.equal(calls, 'ab', 'invoked the second');
113 }); 132 });
114 133
115 var decrypter;
116
117 QUnit.module('Incremental Decryption', { 134 QUnit.module('Incremental Decryption', {
118 setup: function() { 135 beforeEach() {
119 clock = sinon.useFakeTimers(); 136 this.clock = sinon.useFakeTimers();
120 }, 137 },
121 teardown: function() { 138 afterEach() {
122 clock.restore(); 139 this.clock.restore();
123 } 140 }
124 }); 141 });
125 142
126 test('asynchronously decrypts a 4-word block', function() { 143 QUnit.test('asynchronously decrypts a 4-word block', function() {
127 var 144 let key = new Uint32Array([0, 0, 0, 0]);
128 key = new Uint32Array([0, 0, 0, 0]), 145 let initVector = key;
129 initVector = key,
130 // the string "howdy folks" encrypted 146 // the string "howdy folks" encrypted
131 encrypted = new Uint8Array([ 147 let encrypted = new Uint8Array([0xce, 0x90, 0x97, 0xd0,
132 0xce, 0x90, 0x97, 0xd0,
133 0x08, 0x46, 0x4d, 0x18, 148 0x08, 0x46, 0x4d, 0x18,
134 0x4f, 0xae, 0x01, 0x1c, 149 0x4f, 0xae, 0x01, 0x1c,
135 0x82, 0xa8, 0xf0, 0x67]), 150 0x82, 0xa8, 0xf0, 0x67]);
136 decrypted; 151 let decrypted;
137 152 let decrypter = new Decrypter(encrypted,
138 decrypter = new videojs.Hls.Decrypter(encrypted, key, initVector, function(error, result) { 153 key,
154 initVector,
155 function(error, result) {
156 if (error) {
157 throw new Error(error);
158 }
139 decrypted = result; 159 decrypted = result;
140 }); 160 });
141 ok(!decrypted, 'asynchronously decrypts');
142 161
143 clock.tick(decrypter.asyncStream_.delay * 2); 162 QUnit.ok(!decrypted, 'asynchronously decrypts');
163 this.clock.tick(decrypter.asyncStream_.delay * 2);
144 164
145 ok(decrypted, 'completed decryption'); 165 QUnit.ok(decrypted, 'completed decryption');
146 deepEqual('howdy folks', 166 QUnit.deepEqual('howdy folks',
147 stringFromBytes(decrypted), 167 stringFromBytes(decrypted),
148 'decrypts and unpads the result'); 168 'decrypts and unpads the result');
149 }); 169 });
150 170
151 test('breaks up input greater than the step value', function() { 171 QUnit.test('breaks up input greater than the step value', function() {
152 var encrypted = new Int32Array(videojs.Hls.Decrypter.STEP + 4), 172 let encrypted = new Int32Array(Decrypter.STEP + 4);
153 done = false, 173 let done = false;
154 decrypter = new videojs.Hls.Decrypter(encrypted, 174 let decrypter = new Decrypter(encrypted,
155 new Uint32Array(4), 175 new Uint32Array(4),
156 new Uint32Array(4), 176 new Uint32Array(4),
157 function() { 177 function() {
158 done = true; 178 done = true;
159 }); 179 });
160 clock.tick(decrypter.asyncStream_.delay * 2);
161 ok(!done, 'not finished after two ticks');
162 180
163 clock.tick(decrypter.asyncStream_.delay); 181 this.clock.tick(decrypter.asyncStream_.delay * 2);
164 ok(done, 'finished after the last chunk is decrypted'); 182 QUnit.ok(!done, 'not finished after two ticks');
165 });
166 183
167 })(window, window.videojs, window.pkcs7.unpad); 184 this.clock.tick(decrypter.asyncStream_.delay);
185 QUnit.ok(done, 'finished after the last chunk is decrypted');
186 });
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
12 <!-- NOTE in order for test to pass we require sinon 1.10.2 exactly --> 12 <!-- NOTE in order for test to pass we require sinon 1.10.2 exactly -->
13 <script src="/node_modules/sinon/pkg/sinon.js"></script> 13 <script src="/node_modules/sinon/pkg/sinon.js"></script>
14 <script src="/node_modules/qunitjs/qunit/qunit.js"></script> 14 <script src="/node_modules/qunitjs/qunit/qunit.js"></script>
15 <script src="/node_modules/pkcs7/dist/pkcs7.unpad.js"></script>
16 <script src="/node_modules/video.js/dist/video.js"></script> 15 <script src="/node_modules/video.js/dist/video.js"></script>
17 <script src="/node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> 16 <script src="/node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
18 17
...@@ -21,14 +20,12 @@ ...@@ -21,14 +20,12 @@
21 <script src="/dist/videojs-contrib-hls.js"></script> 20 <script src="/dist/videojs-contrib-hls.js"></script>
22 <script src="/src/playlist.js"></script> 21 <script src="/src/playlist.js"></script>
23 <script src="/src/playlist-loader.js"></script> 22 <script src="/src/playlist-loader.js"></script>
24 <script src="/src/decrypter.js"></script>
25 <script src="/src/bin-utils.js"></script> 23 <script src="/src/bin-utils.js"></script>
26 24
27 <script src="/test/videojs-contrib-hls.test.js"></script> 25 <script src="/test/videojs-contrib-hls.test.js"></script>
28 <script src="/dist-test/videojs-contrib-hls.js"></script> 26 <script src="/dist-test/videojs-contrib-hls.js"></script>
29 <script src="/test/playlist.test.js"></script> 27 <script src="/test/playlist.test.js"></script>
30 <script src="/test/playlist-loader.test.js"></script> 28 <script src="/test/playlist-loader.test.js"></script>
31 <script src="/test/decrypter.test.js"></script>
32 29
33 </body> 30 </body>
34 </html> 31 </html>
......
...@@ -12,7 +12,6 @@ var DEFAULTS = { ...@@ -12,7 +12,6 @@ var DEFAULTS = {
12 'node_modules/video.js/dist/video-js.css', 12 'node_modules/video.js/dist/video-js.css',
13 13
14 // REMOVE ME WHEN BROWSERIFIED 14 // REMOVE ME WHEN BROWSERIFIED
15 'node_modules/pkcs7/dist/pkcs7.unpad.js',
16 'node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js', 15 'node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
17 16
18 // these two stub old functionality 17 // these two stub old functionality
...@@ -22,7 +21,6 @@ var DEFAULTS = { ...@@ -22,7 +21,6 @@ var DEFAULTS = {
22 21
23 'src/playlist.js', 22 'src/playlist.js',
24 'src/playlist-loader.js', 23 'src/playlist-loader.js',
25 'src/decrypter.js',
26 'src/bin-utils.js', 24 'src/bin-utils.js',
27 25
28 'test/stub.test.js', 26 'test/stub.test.js',
...@@ -47,7 +45,7 @@ var DEFAULTS = { ...@@ -47,7 +45,7 @@ var DEFAULTS = {
47 ], 45 ],
48 46
49 preprocessors: { 47 preprocessors: {
50 'test/{stub,m3u8}.test.js': ['browserify'] 48 'test/{decrypter,stub,m3u8}.test.js': ['browserify']
51 }, 49 },
52 50
53 reporters: ['dots'], 51 reporters: ['dots'],
......