KeyProvider.kt
3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
* Copyright 2023-2025 LiveKit, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.livekit.android.e2ee
import io.livekit.android.util.LKLog
import livekit.org.webrtc.FrameCryptorFactory
import livekit.org.webrtc.FrameCryptorKeyProvider
class KeyInfo(var participantId: String, var keyIndex: Int, var key: String) {
override fun toString(): String {
return "KeyInfo(participantId='$participantId', keyIndex=$keyIndex)"
}
}
interface KeyProvider {
fun setSharedKey(key: String, keyIndex: Int? = 0): Boolean
fun ratchetSharedKey(keyIndex: Int? = 0): ByteArray
fun exportSharedKey(keyIndex: Int? = 0): ByteArray
fun setKey(key: String, participantId: String?, keyIndex: Int? = 0)
fun ratchetKey(participantId: String, keyIndex: Int? = 0): ByteArray
fun exportKey(participantId: String, keyIndex: Int? = 0): ByteArray
fun setSifTrailer(trailer: ByteArray)
val rtcKeyProvider: FrameCryptorKeyProvider
var enableSharedKey: Boolean
}
class BaseKeyProvider(
ratchetSalt: String = defaultRatchetSalt,
uncryptedMagicBytes: String = defaultMagicBytes,
ratchetWindowSize: Int = defaultRatchetWindowSize,
override var enableSharedKey: Boolean = true,
failureTolerance: Int = defaultFailureTolerance,
keyRingSize: Int = defaultKeyRingSize,
discardFrameWhenCryptorNotReady: Boolean = defaultDiscardFrameWhenCryptorNotReady,
) : KeyProvider {
override val rtcKeyProvider: FrameCryptorKeyProvider
private var keys: MutableMap<String, MutableMap<Int, String>> = mutableMapOf()
init {
this.rtcKeyProvider = FrameCryptorFactory.createFrameCryptorKeyProvider(
enableSharedKey,
ratchetSalt.toByteArray(),
ratchetWindowSize,
uncryptedMagicBytes.toByteArray(),
failureTolerance,
keyRingSize,
discardFrameWhenCryptorNotReady,
)
}
override fun setSharedKey(key: String, keyIndex: Int?): Boolean {
return rtcKeyProvider.setSharedKey(keyIndex ?: 0, key.toByteArray())
}
override fun ratchetSharedKey(keyIndex: Int?): ByteArray {
return rtcKeyProvider.ratchetSharedKey(keyIndex ?: 0)
}
override fun exportSharedKey(keyIndex: Int?): ByteArray {
return rtcKeyProvider.exportSharedKey(keyIndex ?: 0)
}
/**
* Set a key for a participant
* @param key
* @param participantId
* @param keyIndex
*/
override fun setKey(key: String, participantId: String?, keyIndex: Int?) {
if (enableSharedKey) {
return
}
if (participantId == null) {
LKLog.d { "Please provide valid participantId for non-SharedKey mode." }
return
}
var keyInfo = KeyInfo(participantId, keyIndex ?: 0, key)
if (!keys.containsKey(keyInfo.participantId)) {
keys[keyInfo.participantId] = mutableMapOf()
}
keys[keyInfo.participantId]!![keyInfo.keyIndex] = keyInfo.key
rtcKeyProvider.setKey(participantId, keyInfo.keyIndex, key.toByteArray())
}
override fun ratchetKey(participantId: String, keyIndex: Int?): ByteArray {
return rtcKeyProvider.ratchetKey(participantId, keyIndex ?: 0)
}
override fun exportKey(participantId: String, keyIndex: Int?): ByteArray {
return rtcKeyProvider.exportKey(participantId, keyIndex ?: 0)
}
override fun setSifTrailer(trailer: ByteArray) {
rtcKeyProvider.setSifTrailer(trailer)
}
}