Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to use E2ee module in jitis meet utilizing externally managed key handler but not found option to add external key #14704

Open
VeshRaazThapa opened this issue May 2, 2024 · 18 comments

Comments

@VeshRaazThapa
Copy link

Issue: Setting Media Encryption Key and Activating Externally Managed Key Mechanism in Jitsi Meet

Description:

I've successfully activated end-to-end encryption (E2EE) in Jitsi Meet by toggling the option in the security settings. However, I encountered difficulties setting the media encryption key, which led me to hardcode my encryption key in jitsi-meet/react/features/e2ee/middleware.ts.

To ensure the encryption key is properly set when participants join, I've dispatched the toggle button from code using dispatch(toggleE2EE(false));.

Additionally, I tried activating the externally managed key mechanism by setting externallyManagedKey: true in config.js. However, this didn't work as expected, and I had to modify reducer.ts to include the line:

newValue.e2ee = newValue.e2ee || {
    externallyManagedKey: true,
};

I'm seeking guidance on a better approach to set the media encryption key in Jitsi Meet when using an externally managed key handler. Also, I'd like to resolve the issue with activating the externally managed key mechanism.

Steps to Reproduce:

  1. Activate end-to-end encryption in Jitsi Meet.
  2. Attempt to set the media encryption key programmatically.
  3. Set externallyManagedKey: true in config.js.
  4. Observe that the externally managed key mechanism is not activated.
  5. Modify reducer.ts as mentioned to activate the mechanism.

Expected Behavior:

  1. Ability to set the media encryption key programmatically without hardcoding.
  2. Successful activation of the externally managed key mechanism by setting externallyManagedKey: true in config.js.

Server information:

Client information:

  • Browser / app version: chrome
  • Operating System: linux

Additional information:

@damencho
Copy link
Member

damencho commented May 2, 2024

Please, when you have questions or problems use the community forum before opening new issues, thank you.

@saghul
Copy link
Member

saghul commented May 2, 2024

The external key needs to be set using the iframe API, it's not designed for direct user access.

What problem did you have with the automatic key management?

@damencho
Copy link
Member

damencho commented May 2, 2024

Here is an example of setting the key via iframe API and toggling e2ee in the meeting:

const api = new JitsiMeetExternalAPI(

@monidp9
Copy link

monidp9 commented May 14, 2024

I follow the problem @VeshRaazThapa has reported. Specifically, it seems the config.js file is not considered at all. I decommented the e2ee section but when I access e2ee.externallyManagedKey it is undefined.

@saghul
Copy link
Member

saghul commented May 14, 2024

Can you share the full piece of code of what you're trying to do?

@monidp9
Copy link

monidp9 commented May 14, 2024

The app is running on local through make dev. I just modified the UI of E2EESection.tsx. The following is the code snippet.

const E2EESection = ({
    _descriptionResource,
    _enabled,
    _e2eeLabels,
    _everyoneSupportE2EE,
    _toggled,
    dispatch
}: IProps) => {
    const { classes } = useStyles();
    const { t } = useTranslation();
    const [ toggled, setToggled ] = useState(_toggled ?? false);

    useEffect(() => {
        setToggled(_toggled);
    }, [ _toggled ]);

    /**
     * Callback to be invoked when the user toggles E2EE on or off.
     *
     * @private
     * @returns {void}
     */
    const _onToggle = useCallback(() => {
        const newValue = !toggled;

        setToggled(newValue);

        sendAnalytics(createE2EEEvent(`enabled.${String(newValue)}`));
        dispatch(toggleE2EE(newValue));
    }, [ toggled ]);

    const description = _e2eeLabels?.description || t(_descriptionResource ?? '');
    const label = _e2eeLabels?.label || t('dialog.e2eeLabel');
    const warning = _e2eeLabels?.warning || t('dialog.e2eeWarning');

    return (
        <div
            className = { classes.e2eeSection }
            id = 'e2ee-section'>
            <p
                aria-live = 'polite'
                className = { classes.description }
                id = 'e2ee-section-description'>
                {description}
                {!_everyoneSupportE2EE && <br />}
                {!_everyoneSupportE2EE && warning}
            </p>
            <div className = { classes.controlRow }>
                <label htmlFor = 'e2ee-section-switch'>
                    {label}
                </label>
                <Switch
                    checked = { toggled }
                    disabled = { !_enabled }
                    id = 'e2ee-section-switch'
                    onChange = { _onToggle } />
            </div>
            <div className={classes.indicatorRow}>
                <div className={e2ee.externallyManagedKey ? classes.successIndicator : classes.errorIndicator}></div>
                <label>
                    {e2ee.externallyManagedKey ? 'Externally Enabled in config file' : 'Externally Disabled in config file'}
                </label>
            </div>
        </div>
    );
};

In config.js the e2ee section is uncommented.

e2ee: {
      labels: {
        description: 'Description',
        label: 'E2EE',
        tooltip: 'Tooltip',
        warning: 'Warning',
      },
      externallyManagedKey: false
    }

Nontheless the externallyManagedKey is undefined.

@saghul
Copy link
Member

saghul commented May 15, 2024

Nontheless the externallyManagedKey is undefined.

I don't understand. You are configuring externallyManagedKey: false which means the internal mode is going to be used, aka the default.

In addition, you can't just change config.js, since that file is served by the deployment. You should either have your own deployment or use the iframe API and use config overrides to change the settings you want.

@monidp9
Copy link

monidp9 commented May 15, 2024

Ok I got it. Where can I find an example of iframe API? Or maybe another way for reading a config file.

@saghul
Copy link
Member

saghul commented May 15, 2024

Check damencho's comment above.

@monidp9
Copy link

monidp9 commented May 17, 2024

I've tried to include iframe api has below (in my custom component QKDSection.ts)

import React, { useCallback, useEffect, useState, useRef } from 'react';
import { connect } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { IReduxState, IStore } from '../../app/types';
import Switch from '../../base/ui/components/web/Switch';
import { toggleQKD } from '../actions';
import JitsiMeetExternalAPI from '../../../../modules/API/external/external_api';


interface IProps {
    _enabled: boolean;

    _toggled: boolean;

    dispatch: IStore['dispatch'];
}

const useStyles = makeStyles()(theme => {
    return {
        qkdSection: {
            display: 'flex',
            flexDirection: 'column'
        },

        description: {
            fontSize: '13px',
            margin: '15px 0'
        },

        controlRow: {
            display: 'flex',
            justifyContent: 'space-between',
            marginTop: '15px',

            '& label': {
                fontSize: '14px',
                fontWeight: 'bold'
            }
        }
    };
});

const QKDSection = ({
    _enabled,
    _toggled,
    dispatch
}: IProps) => {
    const { classes } = useStyles();
    const [ toggled, setToggled ] = useState(_toggled ?? false);
    
    useEffect(() => {
        setToggled(_toggled);
    }, [_toggled]);

    
    useEffect(() => {
        const domain = "alpha.jitsi.net";
        const options = {
            configOverwrite: {
                e2ee: {
                    labels: {
                        description: 'End to End Encryption',
                        label: 'E2EE',
                        tooltip: '',
                        warning: 'All users must use E2EE',
                    },
                    externallyManagedKey: true,
                }
            }
        };
        console.log("DEBUG " + options.configOverwrite.e2ee.externallyManagedKey);
        const api = new JitsiMeetExternalAPI(domain, options);

        return () => api.dispose(); // Cleanup on unmount
    }, []);

    const _onToggle = useCallback(() => {
        const newValue = !toggled;

        setToggled(newValue);

        dispatch(toggleQKD(newValue));
    }, [ toggled ]);

    return (
        <div
            className = { classes.qkdSection }
            id = 'qkd-section'>
            <p
                aria-live = 'polite'
                className = { classes.description }
                id = 'qkd-section-description'>
                {"Implementazione di QKD"}
            </p>
            <div className = { classes.controlRow }>
                <label htmlFor = 'qkd-section-switch'>
                    {"QKD Toggle"}
                </label>
                <Switch
                    checked = { toggled }
                    disabled = { false }
                    id = 'qkd-section-switch'
                    onChange = { _onToggle } />
            </div>
        </div>
    ); 
};

/**
 * Maps (parts of) the Redux state to the associated props for this component.
 *
 * @param {Object} state - The Redux state.
 * @private
 * @returns {IProps}
 */
function mapStateToProps(state: IReduxState) {
    const { enabled: e2eeEnabled } = state['features/e2ee'];
    const { toggled: qkdToggled } = state['features/qkd'];
    const { e2ee = {} } = state['features/base/config'];

    console.log("DEBUG " + e2ee.externallyManagedKey);
    
    return {
        _enabled: e2eeEnabled,
        _toggled: e2ee.externallyManagedKey ?? qkdToggled
    };
}

export default connect(mapStateToProps)(QKDSection);

However, this create a new instance of the conference which is not what I need. Is there an alternative to iframe api?

@saghul
Copy link
Member

saghul commented May 17, 2024

Sorry, I have trouble understanding what exactly it is you are trying to do. How are you integrating Jitsi onto your app? Where does the external key come from?

@monidp9
Copy link

monidp9 commented May 17, 2024

Sorry I'll try to be more clear. We are not integrating jitsi onto our app, our app is jitsi. We only want to customize the encryption key. Thus, we're modifing jitsi itself. What we want for now is the possibility to read from a confing file the externallyManagedKey in order to activate something.

@saghul
Copy link
Member

saghul commented May 17, 2024

Ok, it's clearer now! Then you'll want to enable the external key, yes, and then dispatch this action:

/**
 * Dispatches an action to set media encryption key.
 *
 * @param {Object} keyInfo - Json containing key information.
 * @param {string} [keyInfo.encryptionKey] - The exported encryption key.
 * @param {number} [keyInfo.index] - The index of the encryption key.
 * @returns {{
 *     type: SET_MEDIA_ENCRYPTION_KEY,
 *     keyInfo: Object
 * }}
 */
export function setMediaEncryptionKey(keyInfo: Object) {
    return {
        type: SET_MEDIA_ENCRYPTION_KEY,
        keyInfo
    };
}

@monidp9
Copy link

monidp9 commented May 17, 2024

Yes but first thing we want to do at the starting of jitsi app is to read in some config file if externallyManagedKey is true or false. How can we do this?

@saghul
Copy link
Member

saghul commented May 17, 2024

The config is set to a global in window. Do you can read it from wherever you want.

@monidp9
Copy link

monidp9 commented May 17, 2024

immagine
Here window.confing.e2ee.externallyManagedKey is undefined.

@saghul
Copy link
Member

saghul commented May 17, 2024

Is it set to something in your config.js ?

@monidp9
Copy link

monidp9 commented May 17, 2024

In config.js

immagine

EDIT:
We are not in deploy mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants