Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

Context.spec.js 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* eslint-disable no-bitwise */
  2. import { Context } from './Context';
  3. import { importKey, ratchet } from './crypto-utils';
  4. /*
  5. function hexdump(buffer) {
  6. const a = new Uint8Array(buffer);
  7. let s = '';
  8. for (let i = 0; i < a.byteLength; i++) {
  9. s += '0x';
  10. s += a[i].toString(16);
  11. s += ' ';
  12. }
  13. return s.trim();
  14. }
  15. */
  16. /* TODO: more tests
  17. * - delta frames
  18. * - frame header is not encrypted
  19. * - different sendCounts
  20. * - different key length
  21. * - ratcheting in decodeFunction
  22. * etc
  23. */
  24. const audioBytes = [ 0xde, 0xad, 0xbe, 0xef ];
  25. const videoBytes = [ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef ];
  26. /**
  27. * generates a dummy audio frame
  28. */
  29. function makeAudioFrame() {
  30. return {
  31. data: new Uint8Array(audioBytes).buffer,
  32. type: undefined, // type is undefined for audio frames.
  33. getMetadata: () => {
  34. return { synchronizationSource: 123 };
  35. }
  36. };
  37. }
  38. /**
  39. * generates a dummy video frame
  40. */
  41. function makeVideoFrame() {
  42. return {
  43. data: new Uint8Array(videoBytes).buffer,
  44. type: 'key',
  45. getMetadata: () => {
  46. return { synchronizationSource: 321 };
  47. }
  48. };
  49. }
  50. describe('E2EE Context', () => {
  51. let sender;
  52. let sendController;
  53. let receiver;
  54. let receiveController;
  55. const key = new Uint8Array([
  56. 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  57. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  58. ]);
  59. beforeEach(() => {
  60. sender = new Context('sender');
  61. receiver = new Context('receiver');
  62. });
  63. describe('encode function', () => {
  64. beforeEach(async () => {
  65. await sender.setKey(key, 0);
  66. await receiver.setKey(key, 0);
  67. });
  68. it('with an audio frame', done => {
  69. sendController = {
  70. enqueue: encodedFrame => {
  71. const data = new Uint8Array(encodedFrame.data);
  72. // An audio frame will have an overhead of 30 bytes and key size:
  73. // 16 bytes authentication tag, 12 bytes iv, iv length (1 byte) and 1 byte key index.
  74. expect(data.byteLength).toEqual(audioBytes.length + 30);
  75. // TODO: provide test vector.
  76. done();
  77. }
  78. };
  79. sender.encodeFunction(makeAudioFrame(), sendController);
  80. });
  81. it('with a video frame', done => {
  82. sendController = {
  83. enqueue: encodedFrame => {
  84. const data = new Uint8Array(encodedFrame.data);
  85. // A video frame will have an overhead of 30 bytes and key size:
  86. // 16 bytes authentication tag, 12 bytes iv, iv length (1 byte) and 1 byte key index.
  87. expect(data.byteLength).toEqual(videoBytes.length + 30);
  88. // TODO: provide test vector.
  89. done();
  90. }
  91. };
  92. sender.encodeFunction(makeVideoFrame(), sendController);
  93. });
  94. });
  95. describe('end-to-end test', () => {
  96. beforeEach(async () => {
  97. await sender.setKey(key, 0);
  98. await receiver.setKey(key, 0);
  99. sendController = {
  100. enqueue: async encodedFrame => {
  101. await receiver.decodeFunction(encodedFrame, receiveController);
  102. }
  103. };
  104. });
  105. it('with an audio frame', done => {
  106. receiveController = {
  107. enqueue: encodedFrame => {
  108. const data = new Uint8Array(encodedFrame.data);
  109. expect(data.byteLength).toEqual(audioBytes.length);
  110. expect(Array.from(data)).toEqual(audioBytes);
  111. done();
  112. }
  113. };
  114. sender.encodeFunction(makeAudioFrame(), sendController);
  115. });
  116. it('with a video frame', done => {
  117. receiveController = {
  118. enqueue: encodedFrame => {
  119. const data = new Uint8Array(encodedFrame.data);
  120. expect(data.byteLength).toEqual(videoBytes.length);
  121. expect(Array.from(data)).toEqual(videoBytes);
  122. done();
  123. }
  124. };
  125. sender.encodeFunction(makeVideoFrame(), sendController);
  126. });
  127. it('the receiver ratchets forward', done => {
  128. receiveController = {
  129. enqueue: encodedFrame => {
  130. const data = new Uint8Array(encodedFrame.data);
  131. expect(data.byteLength).toEqual(audioBytes.length);
  132. expect(Array.from(data)).toEqual(audioBytes);
  133. done();
  134. }
  135. };
  136. const encodeFunction = async () => {
  137. // Ratchet the key. We reimport from the raw bytes.
  138. const material = await importKey(key);
  139. await sender.setKey(await ratchet(material), 0);
  140. sender.encodeFunction(makeAudioFrame(), sendController);
  141. };
  142. encodeFunction();
  143. });
  144. });
  145. });