improvement: Bitwarden checksum URI generation #498
This commit is contained in:
parent
f723997abb
commit
89041d3137
|
@ -210,11 +210,15 @@ data class BitwardenCipher(
|
||||||
val version: Long,
|
val version: Long,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@optics
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Uri(
|
data class Uri(
|
||||||
val uri: String? = null,
|
val uri: String? = null,
|
||||||
|
val uriChecksumBase64: String? = null,
|
||||||
val match: MatchType? = null,
|
val match: MatchType? = null,
|
||||||
) {
|
) {
|
||||||
|
companion object;
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
enum class MatchType {
|
enum class MatchType {
|
||||||
Domain,
|
Domain,
|
||||||
|
|
|
@ -19,6 +19,8 @@ import com.artemchep.keyguard.core.store.bitwarden.BitwardenProfile
|
||||||
import com.artemchep.keyguard.core.store.bitwarden.BitwardenSend
|
import com.artemchep.keyguard.core.store.bitwarden.BitwardenSend
|
||||||
import com.artemchep.keyguard.core.store.bitwarden.BitwardenService
|
import com.artemchep.keyguard.core.store.bitwarden.BitwardenService
|
||||||
import com.artemchep.keyguard.core.store.bitwarden.BitwardenToken
|
import com.artemchep.keyguard.core.store.bitwarden.BitwardenToken
|
||||||
|
import com.artemchep.keyguard.core.store.bitwarden.login
|
||||||
|
import com.artemchep.keyguard.core.store.bitwarden.uris
|
||||||
import com.artemchep.keyguard.data.Database
|
import com.artemchep.keyguard.data.Database
|
||||||
import com.artemchep.keyguard.platform.recordException
|
import com.artemchep.keyguard.platform.recordException
|
||||||
import com.artemchep.keyguard.provider.bitwarden.api.builder.api
|
import com.artemchep.keyguard.provider.bitwarden.api.builder.api
|
||||||
|
@ -575,7 +577,24 @@ class SyncEngine(
|
||||||
localReEncoder = { model ->
|
localReEncoder = { model ->
|
||||||
model
|
model
|
||||||
},
|
},
|
||||||
localDecoder = { local, remote ->
|
localDecoder = { rawLocal, remote ->
|
||||||
|
// Inject the URL checksums into the list of URLs before
|
||||||
|
// processing the entry.
|
||||||
|
val local = BitwardenCipher.login.uris.modify(rawLocal) { uris ->
|
||||||
|
uris
|
||||||
|
.map { uri ->
|
||||||
|
if (uri.uriChecksumBase64 != null) return@map uri
|
||||||
|
val uriChecksumBase64 = kotlin.run {
|
||||||
|
val rawHash =
|
||||||
|
cryptoGenerator.hashSha256(uri.uri.orEmpty().toByteArray())
|
||||||
|
base64Service.encodeToString(rawHash)
|
||||||
|
}
|
||||||
|
uri.copy(
|
||||||
|
uriChecksumBase64 = uriChecksumBase64,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val itemKey = local.keyBase64
|
val itemKey = local.keyBase64
|
||||||
?.let(base64Service::decode)
|
?.let(base64Service::decode)
|
||||||
val (
|
val (
|
||||||
|
|
|
@ -85,6 +85,7 @@ fun BitwardenCipher.Login.Uri.transform(
|
||||||
crypto: BitwardenCrCta,
|
crypto: BitwardenCrCta,
|
||||||
) = copy(
|
) = copy(
|
||||||
uri = crypto.transformString(uri.orEmpty()),
|
uri = crypto.transformString(uri.orEmpty()),
|
||||||
|
uriChecksumBase64 = uriChecksumBase64?.let(crypto::transformString),
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmName("encryptListOfBitwardenCipherLoginFido2Credentials")
|
@JvmName("encryptListOfBitwardenCipherLoginFido2Credentials")
|
||||||
|
|
|
@ -80,6 +80,7 @@ fun BitwardenCipher.Companion.encrypted(
|
||||||
val match = it.match?.domain()
|
val match = it.match?.domain()
|
||||||
BitwardenCipher.Login.Uri(
|
BitwardenCipher.Login.Uri(
|
||||||
uri = it.uri,
|
uri = it.uri,
|
||||||
|
uriChecksumBase64 = it.uriChecksum,
|
||||||
match = match,
|
match = match,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,6 +9,9 @@ data class LoginUriEntity(
|
||||||
@JsonNames("uri")
|
@JsonNames("uri")
|
||||||
@SerialName("Uri")
|
@SerialName("Uri")
|
||||||
val uri: String? = null,
|
val uri: String? = null,
|
||||||
|
@JsonNames("uriChecksum")
|
||||||
|
@SerialName("UriChecksum")
|
||||||
|
val uriChecksum: String? = null,
|
||||||
@JsonNames("match")
|
@JsonNames("match")
|
||||||
@SerialName("Match")
|
@SerialName("Match")
|
||||||
val match: UriMatchTypeEntity? = null,
|
val match: UriMatchTypeEntity? = null,
|
||||||
|
|
|
@ -10,6 +10,8 @@ import kotlinx.serialization.Serializable
|
||||||
data class LoginUriRequest(
|
data class LoginUriRequest(
|
||||||
@SerialName("uri")
|
@SerialName("uri")
|
||||||
val uri: String,
|
val uri: String,
|
||||||
|
@SerialName("uriChecksum")
|
||||||
|
val uriChecksum: String?,
|
||||||
@SerialName("match")
|
@SerialName("match")
|
||||||
val match: UriMatchTypeEntity?,
|
val match: UriMatchTypeEntity?,
|
||||||
) {
|
) {
|
||||||
|
@ -21,6 +23,7 @@ fun LoginUriRequest.Companion.of(
|
||||||
) = kotlin.run {
|
) = kotlin.run {
|
||||||
LoginUriRequest(
|
LoginUriRequest(
|
||||||
uri = requireNotNull(model.uri) { "Login URI request must have a non-null URI!" },
|
uri = requireNotNull(model.uri) { "Login URI request must have a non-null URI!" },
|
||||||
|
uriChecksum = model.uriChecksumBase64,
|
||||||
match = model.match?.let(UriMatchTypeEntity::of),
|
match = model.match?.let(UriMatchTypeEntity::of),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue