@ -255,7 +255,6 @@ object OpenGroupApi {
val queryParameters : Map < String , String > = mapOf ( ) ,
val queryParameters : Map < String , String > = mapOf ( ) ,
val parameters : Any ? = null ,
val parameters : Any ? = null ,
val headers : Map < String , String > = mapOf ( ) ,
val headers : Map < String , String > = mapOf ( ) ,
val isAuthRequired : Boolean = true ,
val body : ByteArray ? = null ,
val body : ByteArray ? = null ,
/ * *
/ * *
* Always `true` under normal circumstances . You might want to disable
* Always `true` under normal circumstances . You might want to disable
@ -301,73 +300,71 @@ object OpenGroupApi {
?: return Promise . ofFail ( Error . NoEd25519KeyPair )
?: return Promise . ofFail ( Error . NoEd25519KeyPair )
val urlRequest = urlBuilder . toString ( )
val urlRequest = urlBuilder . toString ( )
val headers = request . headers . toMutableMap ( )
val headers = request . headers . toMutableMap ( )
if ( request . isAuthRequired ) {
val nonce = sodium . nonce ( 16 )
val nonce = sodium . nonce ( 16 )
val timestamp = TimeUnit . MILLISECONDS . toSeconds ( System . currentTimeMillis ( ) )
val timestamp = TimeUnit . MILLISECONDS . toSeconds ( System . currentTimeMillis ( ) )
var pubKey = " "
var pubKey = " "
var signature = ByteArray ( Sign . BYTES )
var signature = ByteArray ( Sign . BYTES )
var bodyHash = ByteArray ( 0 )
var bodyHash = ByteArray ( 0 )
if ( request . parameters != null ) {
if ( request . parameters != null ) {
val parameterBytes = JsonUtil . toJson ( request . parameters ) . toByteArray ( )
val parameterBytes = JsonUtil . toJson ( request . parameters ) . toByteArray ( )
val parameterHash = ByteArray ( GenericHash . BYTES _MAX )
val parameterHash = ByteArray ( GenericHash . BYTES _MAX )
if ( sodium . cryptoGenericHash (
if ( sodium . cryptoGenericHash (
parameterHash ,
parameterHash ,
parameterHash . size ,
parameterHash . size ,
parameterBytes ,
parameterBytes ,
parameterBytes . size . toLong ( )
parameterBytes . size . toLong ( )
)
)
) {
) {
bodyHash = parameterHash
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 )
} else if ( request . body != null ) {
. plus ( nonce )
val byteHash = ByteArray ( GenericHash . BYTES _MAX )
. plus ( " $timestamp " . toByteArray ( Charsets . US _ASCII ) )
if ( sodium . cryptoGenericHash (
. plus ( request . verb . rawValue . toByteArray ( ) )
byteHash ,
. plus ( " / ${request.endpoint.value} " . toByteArray ( ) )
byteHash . size ,
. plus ( bodyHash )
request . body ,
if ( serverCapabilities . contains ( Capability . BLIND . name . lowercase ( ) ) ) {
request . body . size . toLong ( )
SodiumUtilities . blindedKeyPair ( publicKey , ed25519KeyPair ) ?. let { keyPair ->
)
pubKey = SessionId (
) {
IdPrefix . BLINDED ,
bodyHash = byteHash
keyPair . publicKey . asBytes
}
) . hexString
}
val messageBytes = Hex . fromStringCondensed ( publicKey )
signature = SodiumUtilities . sogsSignature (
. plus ( nonce )
messageBytes ,
. plus ( " $timestamp " . toByteArray ( Charsets . US _ASCII ) )
ed25519KeyPair . secretKey . asBytes ,
. plus ( request . verb . rawValue . toByteArray ( ) )
keyPair . secretKey . asBytes ,
. plus ( " / ${request.endpoint.value} " . toByteArray ( ) )
keyPair . publicKey . asBytes
. plus ( bodyHash )
) ?: return Promise . ofFail ( Error . SigningFailed )
if ( serverCapabilities . isEmpty ( ) || serverCapabilities . contains ( Capability . BLIND . name . lowercase ( ) ) ) {
} ?: return Promise . ofFail ( Error . SigningFailed )
SodiumUtilities . blindedKeyPair ( publicKey , ed25519KeyPair ) ?. let { keyPair ->
} else {
pubKey = SessionId (
pubKey = SessionId (
IdPrefix . UN_ BLINDED,
IdPrefix . BLINDED,
ed25519K eyPair. publicKey . asBytes
k eyPair. publicKey . asBytes
) . hexString
) . hexString
sodium . cryptoSignDetached (
signature ,
signature = SodiumUtilities . sogsSignature (
messageBytes ,
messageBytes ,
messageBytes . size . toLong ( ) ,
ed25519KeyPair . secretKey . asBytes ,
ed25519KeyPair . secretKey . asBytes
keyPair . secretKey . asBytes ,
)
keyPair . publicKey . asBytes
}
) ?: return Promise . ofFail ( Error . SigningFailed )
headers [ " X-SOGS-Nonce " ] = encodeBytes ( nonce )
} ?: return Promise . ofFail ( Error . SigningFailed )
headers [ " X-SOGS-Timestamp " ] = " $timestamp "
} else {
headers [ " X-SOGS-Pubkey " ] = pubKey
pubKey = SessionId (
headers [ " X-SOGS-Signature " ] = encodeBytes ( signature )
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 ( )
val requestBuilder = okhttp3 . Request . Builder ( )
. url ( urlRequest )
. url ( urlRequest )
@ -794,16 +791,14 @@ object OpenGroupApi {
private fun sequentialBatch (
private fun sequentialBatch (
server : String ,
server : String ,
requests : MutableList < BatchRequestInfo < * > > ,
requests : MutableList < BatchRequestInfo < * > >
authRequired : Boolean = true
) : Promise < List < BatchResponse < * > > , Exception > {
) : Promise < List < BatchResponse < * > > , Exception > {
val request = Request (
val request = Request (
verb = POST ,
verb = POST ,
room = null ,
room = null ,
server = server ,
server = server ,
endpoint = Endpoint . Sequence ,
endpoint = Endpoint . Sequence ,
parameters = requests . map { it . request } ,
parameters = requests . map { it . request }
isAuthRequired = authRequired
)
)
return getBatchResponseJson ( request , requests )
return getBatchResponseJson ( request , requests )
}
}
@ -904,7 +899,7 @@ object OpenGroupApi {
}
}
fun getCapabilities ( server : String ) : Promise < Capabilities , Exception > {
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 ->
return getResponseBody ( request ) . map { response ->
JsonUtil . fromJson ( response , Capabilities :: class . java )
JsonUtil . fromJson ( response , Capabilities :: class . java )
}
}
@ -912,8 +907,7 @@ object OpenGroupApi {
fun getCapabilitiesAndRoomInfo (
fun getCapabilitiesAndRoomInfo (
room : String ,
room : String ,
server : String ,
server : String
authRequired : Boolean = true
) : Promise < Pair < Capabilities , RoomInfo > , Exception > {
) : Promise < Pair < Capabilities , RoomInfo > , Exception > {
val requests = mutableListOf < BatchRequestInfo < * > > (
val requests = mutableListOf < BatchRequestInfo < * > > (
BatchRequestInfo (
BatchRequestInfo (
@ -933,7 +927,7 @@ object OpenGroupApi {
responseType = object : TypeReference < RoomInfo > ( ) { }
responseType = object : TypeReference < RoomInfo > ( ) { }
)
)
)
)
return sequentialBatch ( server , requests , authRequired ). map {
return sequentialBatch ( server , requests ). map {
val capabilities = it . firstOrNull ( ) ?. body as ? Capabilities ?: throw Error . ParsingFailed
val capabilities = it . firstOrNull ( ) ?. body as ? Capabilities ?: throw Error . ParsingFailed
val roomInfo = it . lastOrNull ( ) ?. body as ? RoomInfo ?: throw Error . ParsingFailed
val roomInfo = it . lastOrNull ( ) ?. body as ? RoomInfo ?: throw Error . ParsingFailed
capabilities to roomInfo
capabilities to roomInfo