Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ Legend:
| `sip_bridge_shared_secret` | string | | Yes | 🖌️ | Shared secret allowing the SIP bridge to authenticate on the Nextcloud server |
| `signaling_ticket_secret` | string | | Yes | | Secret used to secure the signaling tickets for guests (255 character random string) |
| `signaling_token_alg` | string<br>`ES256`, `ES384`, `RS256`, `RS384`, `RS512` or `EdDSA` | `ES256` | Yes | | Algorithm for the signaling tickets |
| `signaling_token_privkey_*` | string | * | Yes | | Private key for the signaling ticket creation by the server |
| `signaling_token_pubkey_*` | string | * | Yes | | Public key for the signaling ticket creation by the server |
| `signaling_token_privkey` | string | `''` | No | | Private key for the signaling ticket creation by the server |
| `signaling_token_pubkey` | string | `''` | Yes | | Public key for the signaling ticket creation by the server |
| `hosted_signaling_server_nonce` | string | | No | | Temporary nonce while configuring the hosted signaling server |
| `hosted_signaling_server_account_id` | string | | No | | Account identifier of the hosted signaling server |
| `matterbridge_binary` | string | | No | | Path to the matterbridge binary file |
Expand Down
2 changes: 1 addition & 1 deletion lib/Command/Signaling/VerifyKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if ($update) {
$output->writeln('<comment>Stored public key for algorithm ' . strtolower($alg) . ' did not match stored private key.</comment>');
$output->writeln('<info>A new public key was created and stored.</info>');
$this->appConfig->setAppValueString('signaling_token_pubkey_' . strtolower($alg), $publicKeyDerived);
$this->appConfig->setAppValueString(Config::SIGNALING_TOKEN_PUBKEY, $publicKeyDerived);

return 0;
}
Expand Down
23 changes: 17 additions & 6 deletions lib/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ class Config {
public const string CONVERSATIONS_LIST_STYLES = 'conversations_list_styles';
public const string SIGNALING_TICKET_SECRET = 'signaling_ticket_secret';
public const string SIGNALING_TOKEN_ALG = 'signaling_token_alg';
public const string SIGNALING_TOKEN_PRIVKEY = 'signaling_token_privkey';
public const string SIGNALING_TOKEN_PUBKEY = 'signaling_token_pubkey';
public const string HOSTED_SIGNALING_SERVER_NONCE = 'hosted_signaling_server_nonce';
public const string HOSTED_SIGNALING_SERVER_ACCOUNT_ID = 'hosted_signaling_server_account_id';
public const string HOSTED_SIGNALING_SERVER_ACCOUNT = 'hosted_signaling_server_account';
Expand Down Expand Up @@ -691,6 +693,10 @@ public function getSignalingServers(): array {
* @return string
*/
public function getSignalingSecret(): string {
$secret = $this->appConfig->getAppValueString(self::SIGNALING_SERVERS_SECRET);
if (!empty($secret)) {
return $secret;
}
$config = $this->appConfig->getAppValueArray(self::SIGNALING_SERVERS);
return $config['secret'] ?? '';
}
Expand Down Expand Up @@ -742,8 +748,9 @@ private function getSignalingTicketV1(?string $userId): string {
}

private function ensureSignalingTokenKeys(string $alg): void {
$secret = $this->appConfig->getAppValueString('signaling_token_privkey_' . strtolower($alg));
if ($secret) {
$secret = $this->appConfig->getAppValueString(self::SIGNALING_TOKEN_PRIVKEY);
$currentAlg = $this->appConfig->getAppValueString(self::SIGNALING_TOKEN_ALG);
if ($secret && $alg === $currentAlg) {
return;
}

Expand Down Expand Up @@ -776,8 +783,12 @@ private function ensureSignalingTokenKeys(string $alg): void {
throw new \Exception('Unsupported algorithm ' . $alg);
}

$this->appConfig->setAppValueString('signaling_token_privkey_' . strtolower($alg), $secret);
$this->appConfig->setAppValueString('signaling_token_pubkey_' . strtolower($alg), $public);
if ($alg !== $currentAlg) {
$this->appConfig->setAppValueString(self::SIGNALING_TOKEN_ALG, $alg);
}

$this->appConfig->setAppValueString(self::SIGNALING_TOKEN_PRIVKEY, $secret);
$this->appConfig->setAppValueString(self::SIGNALING_TOKEN_PUBKEY, $public);
}

public function getSignalingTokenAlgorithm(): string {
Expand All @@ -790,7 +801,7 @@ public function getSignalingTokenPrivateKey(?string $alg = null): string {
}
$this->ensureSignalingTokenKeys($alg);

return $this->appConfig->getAppValueString('signaling_token_privkey_' . strtolower($alg));
return $this->appConfig->getAppValueString(self::SIGNALING_TOKEN_PRIVKEY);
}

public function getSignalingTokenPublicKey(?string $alg = null): string {
Expand All @@ -799,7 +810,7 @@ public function getSignalingTokenPublicKey(?string $alg = null): string {
}
$this->ensureSignalingTokenKeys($alg);

return $this->appConfig->getAppValueString('signaling_token_pubkey_' . strtolower($alg));
return $this->appConfig->getAppValueString(self::SIGNALING_TOKEN_PUBKEY);
}

public function deriveSignalingTokenPublicKey(#[SensitiveParameter] string $privateKey, string $alg): string {
Expand Down
2 changes: 2 additions & 0 deletions lib/ConfigLexicon.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ public function getAppConfigs(): array {
new Entry(Config::SIP_BRIDGE_DIALOUT, ValueType::BOOL, false, definition: 'SIP dial-out is allowed when a SIP bridge is configured', rename: 'sip_dialout'),
new Entry(Config::SIGNALING_TICKET_SECRET, ValueType::STRING, '', definition: 'Secret used to secure the signaling tickets for guests (255 character random string)', flags: IAppConfig::FLAG_SENSITIVE),
new Entry(Config::SIGNALING_TOKEN_ALG, ValueType::STRING, 'ES256', definition: 'Algorithm for the signaling tickets'),
new Entry(Config::SIGNALING_TOKEN_PRIVKEY, ValueType::STRING, '', definition: 'Private key for the signaling ticket creation by the server', flags: IAppConfig::FLAG_SENSITIVE),
new Entry(Config::SIGNALING_TOKEN_PUBKEY, ValueType::STRING, '', definition: 'Public key for the signaling ticket creation by the server'),
new Entry(Config::SIGNALING_SERVERS, ValueType::ARRAY, ['servers' => [],'secret' => ''], definition: 'List of signaling servers, should be configured via the web interface or the OCC commands', flags: IAppConfig::FLAG_SENSITIVE),
new Entry(Config::SIGNALING_SERVERS_SECRET, ValueType::STRING, '', flags: IAppConfig::FLAG_SENSITIVE),
];
Expand Down
3 changes: 1 addition & 2 deletions lib/Controller/RoomController.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,7 @@ protected function getTalkHashHeader(): array {
json_encode($this->appConfig->getAppValueArray(Config::SIGNALING_SERVERS)),
$this->appConfig->getAppValueString(Config::SIGNALING_TICKET_SECRET),
$this->appConfig->getAppValueString(Config::SIGNALING_TOKEN_ALG),
$this->appConfig->getAppValueString('signaling_token_privkey_' . strtolower($this->appConfig->getAppValueString(Config::SIGNALING_TOKEN_ALG))),
$this->appConfig->getAppValueString('signaling_token_pubkey_' . strtolower($this->appConfig->getAppValueString(Config::SIGNALING_TOKEN_ALG))),
$this->appConfig->getAppValueString(Config::SIGNALING_TOKEN_PUBKEY),
Comment thread
nickvergessen marked this conversation as resolved.
Resolved
$this->appConfig->getAppValueBool(Config::CALL_RECORDING),
json_encode($this->appConfig->getAppValueArray(Config::RECORDING_SERVERS)),
json_encode($this->appConfig->getAppValueArray(Config::ALLOWED_GROUPS_TALK)),
Expand Down
4 changes: 2 additions & 2 deletions lib/Migration/RegenerateSignalingKeys.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public function run(IOutput $output): void {
try {
$this->talkConfig->getSignalingTicket(2, null);
} catch (\Exception) {
$this->appConfig->setAppValueString('signaling_token_privkey_' . strtolower($alg), '');
$this->appConfig->setAppValueString('signaling_token_pubkey_' . strtolower($alg), '');
$this->appConfig->deleteAppValue(Config::SIGNALING_TOKEN_PRIVKEY);
$this->appConfig->deleteAppValue(Config::SIGNALING_TOKEN_PUBKEY);

$this->talkConfig->getSignalingTokenPrivateKey($alg);
}
Expand Down
12 changes: 6 additions & 6 deletions tests/php/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,12 @@ public function testSignalingTicketV2User(string $algo): void {
$appConfig->setAppValueString(Config::SIGNALING_TOKEN_ALG, $algo);

// Make sure new keys are generated.
$appConfig->deleteAppValue('signaling_token_privkey_' . strtolower($algo));
$appConfig->deleteAppValue('signaling_token_pubkey_' . strtolower($algo));
$appConfig->deleteAppValue(Config::SIGNALING_TOKEN_PRIVKEY);
$appConfig->deleteAppValue(Config::SIGNALING_TOKEN_PUBKEY);
$ticket = $helper->getSignalingTicket(Config::SIGNALING_TICKET_V2, 'user1');
$this->assertNotNull($ticket);

$key = new Key($appConfig->getAppValueString('signaling_token_pubkey_' . strtolower($algo)), $algo);
$key = new Key($appConfig->getAppValueString(Config::SIGNALING_TOKEN_PUBKEY), $algo);
$decoded = JWT::decode($ticket, $key);

$this->assertEquals($now, $decoded->iat);
Expand Down Expand Up @@ -414,12 +414,12 @@ public function testSignalingTicketV2Anonymous(string $algo): void {

$appConfig->setAppValueString(Config::SIGNALING_TOKEN_ALG, $algo);
// Make sure new keys are generated.
$appConfig->deleteAppValue('signaling_token_privkey_' . strtolower($algo));
$appConfig->deleteAppValue('signaling_token_pubkey_' . strtolower($algo));
$appConfig->deleteAppValue(Config::SIGNALING_TOKEN_PRIVKEY);
$appConfig->deleteAppValue(Config::SIGNALING_TOKEN_PUBKEY);
$ticket = $helper->getSignalingTicket(Config::SIGNALING_TICKET_V2, null);
$this->assertNotNull($ticket);

$key = new Key($appConfig->getAppValueString('signaling_token_pubkey_' . strtolower($algo)), $algo);
$key = new Key($appConfig->getAppValueString(Config::SIGNALING_TOKEN_PUBKEY), $algo);
$decoded = JWT::decode($ticket, $key);

$this->assertEquals($now, $decoded->iat);
Expand Down
8 changes: 4 additions & 4 deletions tests/php/Controller/SignalingControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -567,8 +567,8 @@ private function validateBackendRandom($data, $random, $checksum) {
return false;
}

$this->appConfig->setAppValueString('signaling_servers_secret', 'MySecretValueMySecretValue1234567890');
$signalingSecret = $this->appConfig->getAppValueString('signaling_servers_secret');
$this->appConfig->setAppValueString(Config::SIGNALING_SERVERS_SECRET, 'MySecretValueMySecretValue1234567890');
$signalingSecret = $this->appConfig->getAppValueString(Config::SIGNALING_SERVERS_SECRET);

$hash = hash_hmac('sha256', $random . $data, $signalingSecret);
return hash_equals($hash, strtolower((string)$checksum));
Expand All @@ -579,8 +579,8 @@ private function calculateBackendChecksum($data, $random) {
return false;
}

$this->appConfig->setAppValueString('signaling_servers_secret', 'MySecretValueMySecretValue1234567890');
$signalingSecret = $this->appConfig->getAppValueString('signaling_servers_secret');
$this->appConfig->setAppValueString(Config::SIGNALING_SERVERS_SECRET, 'MySecretValueMySecretValue1234567890');
$signalingSecret = $this->appConfig->getAppValueString(Config::SIGNALING_SERVERS_SECRET);
$hash = hash_hmac('sha256', $random . $data, $signalingSecret);
return $hash;
}
Expand Down
Loading