ec01a09c by brandonocasey

browserify-p3: decrypter

convert decrypter module to es6/node/browserify
stub old functionalify to get all tests working
updated scripts to keep builds and tests working
1 parent a8daa7f7
...@@ -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([
59 0x14, 0xf5, 0xfe, 0x74, 40 0x14, 0xf5, 0xfe, 0x74,
60 0x69, 0x66, 0xf2, 0x92, 41 0x69, 0x66, 0xf2, 0x92,
61 0x65, 0x1c, 0x22, 0x88, 42 0x65, 0x1c, 0x22, 0x88,
...@@ -67,38 +48,38 @@ test('decrypts multiple AES-128 blocks with CBC', function() { ...@@ -67,38 +48,38 @@ test('decrypts multiple AES-128 blocks with CBC', function() {
67 0xe9, 0x4e, 0x29, 0xb3 48 0xe9, 0x4e, 0x29, 0xb3
68 ]); 49 ]);
69 50
70 deepEqual('0123456789abcdef01234', 51 QUnit.deepEqual('0123456789abcdef01234',
71 stringFromBytes(unpad(videojs.Hls.decrypt(encrypted, key, initVector))), 52 stringFromBytes(unpad(decrypt(encrypted, key, initVector))),
72 'decrypted multiple blocks'); 53 'decrypted multiple blocks');
73 }); 54 });
74 55
75 var clock;
76
77 QUnit.module('Incremental Processing', { 56 QUnit.module('Incremental Processing', {
78 setup: function() { 57 beforeEach() {
79 clock = sinon.useFakeTimers(); 58 this.clock = sinon.useFakeTimers();
80 }, 59 },
81 teardown: function() { 60 afterEach() {
82 clock.restore(); 61 this.clock.restore();
83 } 62 }
84 }); 63 });
85 64
86 test('executes a callback after a timeout', function() { 65 QUnit.test('executes a callback after a timeout', function() {
87 var asyncStream = new videojs.Hls.AsyncStream(), 66 let asyncStream = new AsyncStream();
88 calls = ''; 67 let calls = '';
68
89 asyncStream.push(function() { 69 asyncStream.push(function() {
90 calls += 'a'; 70 calls += 'a';
91 }); 71 });
92 72
93 clock.tick(asyncStream.delay); 73 this.clock.tick(asyncStream.delay);
94 equal(calls, 'a', 'invoked the callback once'); 74 QUnit.equal(calls, 'a', 'invoked the callback once');
95 clock.tick(asyncStream.delay); 75 this.clock.tick(asyncStream.delay);
96 equal(calls, 'a', 'only invoked the callback once'); 76 QUnit.equal(calls, 'a', 'only invoked the callback once');
97 }); 77 });
98 78
99 test('executes callback in series', function() { 79 QUnit.test('executes callback in series', function() {
100 var asyncStream = new videojs.Hls.AsyncStream(), 80 let asyncStream = new AsyncStream();
101 calls = ''; 81 let calls = '';
82
102 asyncStream.push(function() { 83 asyncStream.push(function() {
103 calls += 'a'; 84 calls += 'a';
104 }); 85 });
...@@ -106,62 +87,68 @@ test('executes callback in series', function() { ...@@ -106,62 +87,68 @@ test('executes callback in series', function() {
106 calls += 'b'; 87 calls += 'b';
107 }); 88 });
108 89
109 clock.tick(asyncStream.delay); 90 this.clock.tick(asyncStream.delay);
110 equal(calls, 'a', 'invoked the first callback'); 91 QUnit.equal(calls, 'a', 'invoked the first callback');
111 clock.tick(asyncStream.delay); 92 this.clock.tick(asyncStream.delay);
112 equal(calls, 'ab', 'invoked the second'); 93 QUnit.equal(calls, 'ab', 'invoked the second');
113 }); 94 });
114 95
115 var decrypter;
116
117 QUnit.module('Incremental Decryption', { 96 QUnit.module('Incremental Decryption', {
118 setup: function() { 97 beforeEach() {
119 clock = sinon.useFakeTimers(); 98 this.clock = sinon.useFakeTimers();
120 }, 99 },
121 teardown: function() { 100 afterEach() {
122 clock.restore(); 101 this.clock.restore();
123 } 102 }
124 }); 103 });
125 104
126 test('asynchronously decrypts a 4-word block', function() { 105 QUnit.test('asynchronously decrypts a 4-word block', function() {
127 var 106 let key = new Uint32Array([0, 0, 0, 0]);
128 key = new Uint32Array([0, 0, 0, 0]), 107 let initVector = key;
129 initVector = key,
130 // the string "howdy folks" encrypted 108 // the string "howdy folks" encrypted
131 encrypted = new Uint8Array([ 109 let encrypted = new Uint8Array([
132 0xce, 0x90, 0x97, 0xd0, 110 0xce, 0x90, 0x97, 0xd0,
133 0x08, 0x46, 0x4d, 0x18, 111 0x08, 0x46, 0x4d, 0x18,
134 0x4f, 0xae, 0x01, 0x1c, 112 0x4f, 0xae, 0x01, 0x1c,
135 0x82, 0xa8, 0xf0, 0x67]), 113 0x82, 0xa8, 0xf0, 0x67
136 decrypted; 114 ]);
137 115 let decrypted;
138 decrypter = new videojs.Hls.Decrypter(encrypted, key, initVector, function(error, result) { 116 let decrypter = new Decrypter(
117 encrypted,
118 key,
119 initVector,
120 function(error, result) {
121 if (error) {
122 throw new Error(error);
123 }
139 decrypted = result; 124 decrypted = result;
140 }); 125 }
141 ok(!decrypted, 'asynchronously decrypts'); 126 );
142 127
143 clock.tick(decrypter.asyncStream_.delay * 2); 128 QUnit.ok(!decrypted, 'asynchronously decrypts');
129 this.clock.tick(decrypter.asyncStream_.delay * 2);
144 130
145 ok(decrypted, 'completed decryption'); 131 QUnit.ok(decrypted, 'completed decryption');
146 deepEqual('howdy folks', 132 QUnit.deepEqual('howdy folks',
147 stringFromBytes(decrypted), 133 stringFromBytes(decrypted),
148 'decrypts and unpads the result'); 134 'decrypts and unpads the result');
149 }); 135 });
150 136
151 test('breaks up input greater than the step value', function() { 137 QUnit.test('breaks up input greater than the step value', function() {
152 var encrypted = new Int32Array(videojs.Hls.Decrypter.STEP + 4), 138 let encrypted = new Int32Array(Decrypter.STEP + 4);
153 done = false, 139 let done = false;
154 decrypter = new videojs.Hls.Decrypter(encrypted, 140 let decrypter = new Decrypter(
141 encrypted,
155 new Uint32Array(4), 142 new Uint32Array(4),
156 new Uint32Array(4), 143 new Uint32Array(4),
157 function() { 144 function() {
158 done = true; 145 done = true;
159 }); 146 }
160 clock.tick(decrypter.asyncStream_.delay * 2); 147 );
161 ok(!done, 'not finished after two ticks');
162 148
163 clock.tick(decrypter.asyncStream_.delay); 149 this.clock.tick(decrypter.asyncStream_.delay * 2);
164 ok(done, 'finished after the last chunk is decrypted'); 150 QUnit.ok(!done, 'not finished after two ticks');
165 });
166 151
167 })(window, window.videojs, window.pkcs7.unpad); 152 this.clock.tick(decrypter.asyncStream_.delay);
153 QUnit.ok(done, 'finished after the last chunk is decrypted');
154 });
......
...@@ -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'],
......