Финальный обмен ключами шифрования, все готово для установки WebRTC соединения

This commit is contained in:
RoyceDa
2026-03-11 17:22:29 +02:00
parent e06d58facf
commit e79282755b
3 changed files with 36 additions and 5 deletions

View File

@@ -26,6 +26,10 @@ export interface CallContextValue {
export enum CallState {
CONNECTING,
KEY_EXCHANGE,
/**
* Финальная стадия сигналинга, на которой обе стороны обменялись ключами и теперь устанавливают защищенный канал связи для звонка,
* через WebRTC, и готовятся к активному звонку.
*/
WEB_RTC_EXCHANGE,
ACTIVE,
ENDED,
@@ -59,6 +63,7 @@ export function CallProvider(props : CallProviderProps) {
const [sessionKeys, setSessionKeys] = useState<nacl.BoxKeyPair | null>(null);
const send = useSender();
const publicKey = usePublicKey();
const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
const roleRef = useRef<CallRole | null>(null);
const [sharedSecret, setSharedSecret] = useState<string>("");
@@ -74,10 +79,24 @@ export function CallProvider(props : CallProviderProps) {
* У нас уже есть активный звонок, игнорируем все сигналы, кроме сигналов от текущего звонка
*/
if(packet.getSrc() != activeCall){
console.info("Received signal from " + packet.getSrc() + " but active call is with " + activeCall + ", ignoring");
info("Received signal for another call, ignoring");
return;
}
}
if(signalType == SignalType.END_CALL){
/**
* Сбросили звонок
*/
setActiveCall("");
setCallState(CallState.ENDED);
setShowCallView(false);
setSessionKeys(null);
setSharedSecret("");
setDuration(0);
roleRef.current = null;
return;
}
if(signalType == SignalType.CALL){
/**
* Нам поступает звонок
@@ -87,6 +106,7 @@ export function CallProvider(props : CallProviderProps) {
setShowCallView(true);
}
if(signalType == SignalType.KEY_EXCHANGE && roleRef.current == CallRole.CALLER){
console.info("EXCHANGE SIGNAL RECEIVED, CALLER ROLE");
/**
* Другая сторона сгенерировала ключи для сессии и отправила нам публичную часть,
* теперь мы можем создать общую секретную сессию для шифрования звонка
@@ -105,12 +125,14 @@ export function CallProvider(props : CallProviderProps) {
*/
const signalPacket = new PacketSignal();
signalPacket.setSrc(publicKey);
signalPacket.setDst(packet.getDst());
signalPacket.setDst(packet.getSrc());
signalPacket.setSignalType(SignalType.KEY_EXCHANGE);
signalPacket.setSharedPublic(Buffer.from(sessionKeys.publicKey).toString('hex'));
send(signalPacket);
setCallState(CallState.WEB_RTC_EXCHANGE);
}
if(signalType == SignalType.KEY_EXCHANGE && roleRef.current == CallRole.CALLEE){
console.info("EXCHANGE SIGNAL RECEIVED, CALLEE ROLE");
/**
* Мы отправили свою публичную часть ключа другой стороне,
* теперь мы получили ее публичную часть и можем создать общую
@@ -128,6 +150,7 @@ export function CallProvider(props : CallProviderProps) {
const computedSharedSecret = nacl.box.before(Buffer.from(sharedPublic, 'hex'), sessionKeys.secretKey);
info("Generated shared secret for call session: " + Buffer.from(computedSharedSecret).toString('hex'));
setSharedSecret(Buffer.from(computedSharedSecret).toString('hex'));
setCallState(CallState.WEB_RTC_EXCHANGE);
}
}, [activeCall, sessionKeys]);
@@ -143,6 +166,7 @@ export function CallProvider(props : CallProviderProps) {
setCallState(CallState.CONNECTING);
setShowCallView(true);
const signalPacket = new PacketSignal();
signalPacket.setSrc(publicKey);
signalPacket.setDst(dialog);
signalPacket.setSignalType(SignalType.CALL);
send(signalPacket);
@@ -150,6 +174,12 @@ export function CallProvider(props : CallProviderProps) {
}
const close = () => {
const packetSignal = new PacketSignal();
packetSignal.setSrc(publicKey);
packetSignal.setDst(activeCall);
packetSignal.setSignalType(SignalType.END_CALL);
send(packetSignal);
peerConnectionRef.current = null;
setActiveCall("");
setCallState(CallState.ENDED);
setShowCallView(false);
@@ -170,6 +200,7 @@ export function CallProvider(props : CallProviderProps) {
*/
const keys = generateSessionKeys();
const signalPacket = new PacketSignal();
signalPacket.setSrc(publicKey);
signalPacket.setDst(activeCall);
signalPacket.setSignalType(SignalType.KEY_EXCHANGE);
signalPacket.setSharedPublic(Buffer.from(keys.publicKey).toString('hex'));

View File

@@ -5,7 +5,7 @@ export enum SignalType {
CALL = 0,
KEY_EXCHANGE = 1,
ACTIVE_CALL = 2,
END_CALL = 3
END_CALL = 3
}
/**

View File

@@ -1,10 +1,10 @@
export const SERVERS = [
//'wss://cdn.rosetta-im.com',
//'ws://10.211.55.2:3000',
//'ws://127.0.0.1:3000',
'wss://wss.rosetta.im'
'ws://127.0.0.1:3000',
//'wss://wss.rosetta.im'
];
export function selectServer(): string {
const idx = Math.floor(Math.random() * SERVERS.length);
return SERVERS[idx];