mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 10:05:15 +00:00
Merge pull request #1026 from ceokot/sogs-auth
fix: Authenticate all Open Group API calls
This commit is contained in:
commit
1619277b4f
@ -37,6 +37,7 @@ class BackgroundGroupAddJob(val joinUrl: String): Job {
|
||||
delegate?.handleJobFailed(this, dispatcherName, DuplicateGroupException())
|
||||
return
|
||||
}
|
||||
|
||||
storage.addOpenGroup(openGroup.joinUrl())
|
||||
storage.onOpenGroupAdded(openGroup.server, openGroup.room)
|
||||
} catch (e: Exception) {
|
||||
|
@ -273,7 +273,6 @@ object OpenGroupApi {
|
||||
val queryParameters: Map<String, String> = mapOf(),
|
||||
val parameters: Any? = null,
|
||||
val headers: Map<String, String> = mapOf(),
|
||||
val isAuthRequired: Boolean = true,
|
||||
val body: ByteArray? = null,
|
||||
/**
|
||||
* Always `true` under normal circumstances. You might want to disable
|
||||
@ -319,73 +318,72 @@ object OpenGroupApi {
|
||||
?: return Promise.ofFail(Error.NoEd25519KeyPair)
|
||||
val urlRequest = urlBuilder.toString()
|
||||
val headers = request.headers.toMutableMap()
|
||||
if (request.isAuthRequired) {
|
||||
val nonce = sodium.nonce(16)
|
||||
val timestamp = TimeUnit.MILLISECONDS.toSeconds(SnodeAPI.nowWithOffset)
|
||||
var pubKey = ""
|
||||
var signature = ByteArray(Sign.BYTES)
|
||||
var bodyHash = ByteArray(0)
|
||||
if (request.parameters != null) {
|
||||
val parameterBytes = JsonUtil.toJson(request.parameters).toByteArray()
|
||||
val parameterHash = ByteArray(GenericHash.BYTES_MAX)
|
||||
if (sodium.cryptoGenericHash(
|
||||
parameterHash,
|
||||
parameterHash.size,
|
||||
parameterBytes,
|
||||
parameterBytes.size.toLong()
|
||||
)
|
||||
) {
|
||||
bodyHash = parameterHash
|
||||
}
|
||||
} else if (request.body != null) {
|
||||
val byteHash = ByteArray(GenericHash.BYTES_MAX)
|
||||
if (sodium.cryptoGenericHash(
|
||||
byteHash,
|
||||
byteHash.size,
|
||||
request.body,
|
||||
request.body.size.toLong()
|
||||
)
|
||||
) {
|
||||
bodyHash = byteHash
|
||||
}
|
||||
}
|
||||
val messageBytes = Hex.fromStringCondensed(publicKey)
|
||||
.plus(nonce)
|
||||
.plus("$timestamp".toByteArray(Charsets.US_ASCII))
|
||||
.plus(request.verb.rawValue.toByteArray())
|
||||
.plus("/${request.endpoint.value}".toByteArray())
|
||||
.plus(bodyHash)
|
||||
if (serverCapabilities.isEmpty() || serverCapabilities.contains(Capability.BLIND.name.lowercase())) {
|
||||
SodiumUtilities.blindedKeyPair(publicKey, ed25519KeyPair)?.let { keyPair ->
|
||||
pubKey = SessionId(
|
||||
IdPrefix.BLINDED,
|
||||
keyPair.publicKey.asBytes
|
||||
).hexString
|
||||
|
||||
signature = SodiumUtilities.sogsSignature(
|
||||
messageBytes,
|
||||
ed25519KeyPair.secretKey.asBytes,
|
||||
keyPair.secretKey.asBytes,
|
||||
keyPair.publicKey.asBytes
|
||||
) ?: return Promise.ofFail(Error.SigningFailed)
|
||||
} ?: return Promise.ofFail(Error.SigningFailed)
|
||||
} else {
|
||||
pubKey = SessionId(
|
||||
IdPrefix.UN_BLINDED,
|
||||
ed25519KeyPair.publicKey.asBytes
|
||||
).hexString
|
||||
sodium.cryptoSignDetached(
|
||||
signature,
|
||||
messageBytes,
|
||||
messageBytes.size.toLong(),
|
||||
ed25519KeyPair.secretKey.asBytes
|
||||
val nonce = sodium.nonce(16)
|
||||
val timestamp = TimeUnit.MILLISECONDS.toSeconds(SnodeAPI.nowWithOffset)
|
||||
var pubKey = ""
|
||||
var signature = ByteArray(Sign.BYTES)
|
||||
var bodyHash = ByteArray(0)
|
||||
if (request.parameters != null) {
|
||||
val parameterBytes = JsonUtil.toJson(request.parameters).toByteArray()
|
||||
val parameterHash = ByteArray(GenericHash.BYTES_MAX)
|
||||
if (sodium.cryptoGenericHash(
|
||||
parameterHash,
|
||||
parameterHash.size,
|
||||
parameterBytes,
|
||||
parameterBytes.size.toLong()
|
||||
)
|
||||
) {
|
||||
bodyHash = parameterHash
|
||||
}
|
||||
} else if (request.body != null) {
|
||||
val byteHash = ByteArray(GenericHash.BYTES_MAX)
|
||||
if (sodium.cryptoGenericHash(
|
||||
byteHash,
|
||||
byteHash.size,
|
||||
request.body,
|
||||
request.body.size.toLong()
|
||||
)
|
||||
) {
|
||||
bodyHash = byteHash
|
||||
}
|
||||
headers["X-SOGS-Nonce"] = encodeBytes(nonce)
|
||||
headers["X-SOGS-Timestamp"] = "$timestamp"
|
||||
headers["X-SOGS-Pubkey"] = pubKey
|
||||
headers["X-SOGS-Signature"] = encodeBytes(signature)
|
||||
}
|
||||
val messageBytes = Hex.fromStringCondensed(publicKey)
|
||||
.plus(nonce)
|
||||
.plus("$timestamp".toByteArray(Charsets.US_ASCII))
|
||||
.plus(request.verb.rawValue.toByteArray())
|
||||
.plus("/${request.endpoint.value}".toByteArray())
|
||||
.plus(bodyHash)
|
||||
if (serverCapabilities.isEmpty() || serverCapabilities.contains(Capability.BLIND.name.lowercase())) {
|
||||
SodiumUtilities.blindedKeyPair(publicKey, ed25519KeyPair)?.let { keyPair ->
|
||||
pubKey = SessionId(
|
||||
IdPrefix.BLINDED,
|
||||
keyPair.publicKey.asBytes
|
||||
).hexString
|
||||
|
||||
signature = SodiumUtilities.sogsSignature(
|
||||
messageBytes,
|
||||
ed25519KeyPair.secretKey.asBytes,
|
||||
keyPair.secretKey.asBytes,
|
||||
keyPair.publicKey.asBytes
|
||||
) ?: return Promise.ofFail(Error.SigningFailed)
|
||||
} ?: return Promise.ofFail(Error.SigningFailed)
|
||||
} else {
|
||||
pubKey = SessionId(
|
||||
IdPrefix.UN_BLINDED,
|
||||
ed25519KeyPair.publicKey.asBytes
|
||||
).hexString
|
||||
sodium.cryptoSignDetached(
|
||||
signature,
|
||||
messageBytes,
|
||||
messageBytes.size.toLong(),
|
||||
ed25519KeyPair.secretKey.asBytes
|
||||
)
|
||||
}
|
||||
headers["X-SOGS-Nonce"] = encodeBytes(nonce)
|
||||
headers["X-SOGS-Timestamp"] = "$timestamp"
|
||||
headers["X-SOGS-Pubkey"] = pubKey
|
||||
headers["X-SOGS-Signature"] = encodeBytes(signature)
|
||||
|
||||
val requestBuilder = okhttp3.Request.Builder()
|
||||
.url(urlRequest)
|
||||
@ -927,7 +925,7 @@ object OpenGroupApi {
|
||||
}
|
||||
|
||||
fun getCapabilities(server: String): Promise<Capabilities, Exception> {
|
||||
val request = Request(verb = GET, room = null, server = server, endpoint = Endpoint.Capabilities, isAuthRequired = false)
|
||||
val request = Request(verb = GET, room = null, server = server, endpoint = Endpoint.Capabilities)
|
||||
return getResponseBody(request).map { response ->
|
||||
JsonUtil.fromJson(response, Capabilities::class.java)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user