您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ManagedKeyHandler.js 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import { getLogger } from '@jitsi/logger';
  2. import debounce from 'lodash.debounce';
  3. import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
  4. import { KeyHandler } from './KeyHandler';
  5. import { OlmAdapter } from './OlmAdapter';
  6. import { importKey, ratchet } from './crypto-utils';
  7. const logger = getLogger(__filename);
  8. // Period which we'll wait before updating / rotating our keys when a participant
  9. // joins or leaves.
  10. const DEBOUNCE_PERIOD = 5000;
  11. /**
  12. * This module integrates {@link E2EEContext} with {@link OlmAdapter} in order to distribute the keys for encryption.
  13. */
  14. /*
  15. // zq.aoij aaa=a
  16. try {
  17. glob_rx?.fns?.loadEvent?.("mkh start.2",{ManagedKeyHandler})
  18. } catch (err){
  19. glob_rx?.fns?.loadEvent?.("mkh start.err",{err})
  20. }
  21. */
  22. // glob_rx?.fns?.loadEvent?.("mkh start.2",{ManagedKeyHandler})
  23. // glob_rx?.fns?.loadEvent?.("mkh start.2",{})
  24. export class ManagedKeyHandler extends KeyHandler {
  25. /**
  26. * Build a new AutomaticKeyHandler instance, which will be used in a given conference.
  27. */
  28. constructor(conference) {
  29. super(conference);
  30. console.log("ManagedKeyHandler _CONSTRUCTED???????")
  31. if (glob_rx?.ljm?.i){
  32. glob_rx.ljm.i.mkh_inst = this
  33. clog("ManagedKeyHandler ljm constructed,??...,")
  34. console.trace("mkh_trc.")
  35. }
  36. glob_rx?.fns?.loadEvent?.("mkh constructed",{that:this})
  37. if (glob_rx?.fns?.glob_dev_fncb("mkh_dev")){
  38. this._fakeKey = undefined
  39. this.mkh_dev =true
  40. }
  41. this._key = undefined;
  42. this._conferenceJoined = false;
  43. this._olmAdapter = new OlmAdapter(conference);
  44. this._rotateKey = debounce(this._rotateKeyImpl, DEBOUNCE_PERIOD);
  45. this._ratchetKey = debounce(this._ratchetKeyImpl, DEBOUNCE_PERIOD);
  46. // Olm signalling events.
  47. this._olmAdapter.on(
  48. OlmAdapter.events.PARTICIPANT_KEY_UPDATED,
  49. this._onParticipantKeyUpdated.bind(this));
  50. this._olmAdapter.on(
  51. OlmAdapter.events.PARTICIPANT_SAS_READY,
  52. this._onParticipantSasReady.bind(this));
  53. this._olmAdapter.on(
  54. OlmAdapter.events.PARTICIPANT_SAS_AVAILABLE,
  55. this._onParticipantSasAvailable.bind(this));
  56. this._olmAdapter.on(
  57. OlmAdapter.events.PARTICIPANT_VERIFICATION_COMPLETED,
  58. this._onParticipantVerificationCompleted.bind(this));
  59. this.conference.on(
  60. JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
  61. this._onParticipantPropertyChanged.bind(this));
  62. this.conference.on(
  63. JitsiConferenceEvents.USER_JOINED,
  64. this._onParticipantJoined.bind(this));
  65. this.conference.on(
  66. JitsiConferenceEvents.USER_LEFT,
  67. this._onParticipantLeft.bind(this));
  68. this.conference.on(
  69. JitsiConferenceEvents.CONFERENCE_JOINED,
  70. () => {
  71. this._conferenceJoined = true;
  72. });
  73. }
  74. /**
  75. * Returns the sasVerficiation object.
  76. *
  77. * @returns {Object}
  78. */
  79. get sasVerification() {
  80. clog("ljm:sasVerification")
  81. return this._olmAdapter;
  82. }
  83. /**
  84. * When E2EE is enabled it initializes sessions and sets the key.
  85. * Cleans up the sessions when disabled.
  86. *
  87. * @param {boolean} enabled - whether E2EE should be enabled or not.
  88. * @returns {void}
  89. */
  90. async _setEnabled(enabled) {
  91. if (enabled) {
  92. await this._olmAdapter.initSessions();
  93. } else {
  94. this._olmAdapter.clearAllParticipantsSessions();
  95. }
  96. // Generate a random key in case we are enabling.
  97. this._key = enabled ? this._generateKey() : false;
  98. // Send it to others using the E2EE olm channel.
  99. const index = await this._olmAdapter.updateKey(this._key);
  100. // Set our key so we begin encrypting.
  101. this.e2eeCtx.setKey(this.conference.myUserId(), this._key, index);
  102. }
  103. /**
  104. * Handles an update in a participant's presence property.
  105. *
  106. * @param {JitsiParticipant} participant - The participant.
  107. * @param {string} name - The name of the property that changed.
  108. * @param {*} oldValue - The property's previous value.
  109. * @param {*} newValue - The property's new value.
  110. * @private
  111. */
  112. async _onParticipantPropertyChanged(participant, name, oldValue, newValue) {
  113. switch (name) {
  114. case 'e2ee.idKey':
  115. logger.debug(`Participant ${participant.getId()} updated their id key: ${newValue}`);
  116. break;
  117. case 'e2ee.enabled':
  118. if (!newValue && this.enabled) {
  119. this._olmAdapter.clearParticipantSession(participant);
  120. }
  121. break;
  122. }
  123. }
  124. /**
  125. * Advances (using ratcheting) the current key when a new participant joins the conference.
  126. * @private
  127. */
  128. _onParticipantJoined() {
  129. if (this._conferenceJoined && this.enabled) {
  130. this._ratchetKey();
  131. }
  132. }
  133. /**
  134. * Rotates the current key when a participant leaves the conference.
  135. * @private
  136. */
  137. _onParticipantLeft(id) {
  138. this.e2eeCtx.cleanup(id);
  139. if (this.enabled) {
  140. this._rotateKey();
  141. }
  142. }
  143. /**
  144. * Rotates the local key. Rotating the key implies creating a new one, then distributing it
  145. * to all participants and once they all received it, start using it.
  146. *
  147. * @private
  148. */
  149. async _rotateKeyImpl() {
  150. console.log("ljm_dbg _rotateKeyImpl")
  151. logger.debug('Rotating key');
  152. this._key = this._generateKey();
  153. const index = await this._olmAdapter.updateKey(this._key);
  154. this.e2eeCtx.setKey(this.conference.myUserId(), this._key, index);
  155. }
  156. /**
  157. * Advances the current key by using ratcheting.
  158. *
  159. * @private
  160. */
  161. async _ratchetKeyImpl() {
  162. console.log("ljm_dbg _ratchetKeyImpl")
  163. logger.debug('Ratchetting key');
  164. const material = await importKey(this._key);
  165. const newKey = await ratchet(material);
  166. this._key = new Uint8Array(newKey);
  167. // updateCurrentKey updateCurrentMediaKey
  168. const index = this._olmAdapter.updateCurrentMediaKey(this._key);
  169. // const index = this._olmAdapter.updateCurrentKey(this._key);
  170. this.e2eeCtx.setKey(this.conference.myUserId(), this._key, index);
  171. }
  172. /**
  173. * Handles an update in a participant's key.
  174. *
  175. * @param {string} id - The participant ID.
  176. * @param {Uint8Array | boolean} key - The new key for the participant.
  177. * @param {Number} index - The new key's index.
  178. * @private
  179. */
  180. _onParticipantKeyUpdated(id, key, index) {
  181. logger.debug(`Participant ${id} updated their key`);
  182. this.e2eeCtx.setKey(id, key, index);
  183. }
  184. /**
  185. * Handles the SAS ready event.
  186. *
  187. * @param {string} pId - The participant ID.
  188. * @param {Uint8Array} sas - The bytes from sas.generate_bytes..
  189. * @private
  190. */
  191. _onParticipantSasReady(pId, sas) {
  192. this.conference.eventEmitter.emit(JitsiConferenceEvents.E2EE_VERIFICATION_READY, pId, sas);
  193. }
  194. /**
  195. * Handles the sas available event.
  196. *
  197. * @param {string} pId - The participant ID.
  198. * @private
  199. */
  200. _onParticipantSasAvailable(pId) {
  201. this.conference.eventEmitter.emit(JitsiConferenceEvents.E2EE_VERIFICATION_AVAILABLE, pId);
  202. }
  203. /**
  204. * Handles the SAS completed event.
  205. *
  206. * @param {string} pId - The participant ID.
  207. * @param {boolean} success - Wheter the verification was succesfull.
  208. * @private
  209. */
  210. _onParticipantVerificationCompleted(pId, success, message) {
  211. this.conference.eventEmitter.emit(JitsiConferenceEvents.E2EE_VERIFICATION_COMPLETED, pId, success, message);
  212. }
  213. /**
  214. * Generates a new 256 bit random key.
  215. *
  216. * @returns {Uint8Array}
  217. * @private
  218. */
  219. _generateKey() {
  220. return window.crypto.getRandomValues(new Uint8Array(32));
  221. }
  222. }
  223. if (window?.glob_rx?.ljm?.j){
  224. glob_rx.ljm.j.mkh = {KeyHandler,OlmAdapter,importKey, ratchet,debounce,JitsiConferenceEvents,ManagedKeyHandler,}
  225. }
  226. glob_rx?.fns?.loadEvent?.("mkh eof",{ManagedKeyHandler})