Fix warnings in the SDK

This commit is contained in:
Benoit Marty 2019-10-08 16:10:53 +02:00
parent 6de64cbedd
commit a9c474105a
29 changed files with 142 additions and 159 deletions

View file

@ -136,6 +136,7 @@ data class Event(
* @return the event content
*/
fun getClearContent(): Content? {
@Suppress("UNCHECKED_CAST")
return mxDecryptionResult?.payload?.get("content") as? Content ?: content
}

View file

@ -31,9 +31,7 @@ import im.vector.matrix.android.api.failure.Failure
import im.vector.matrix.android.api.listeners.ProgressListener
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
import im.vector.matrix.android.api.session.crypto.keyshare.RoomKeysRequestListener
import im.vector.matrix.android.api.session.crypto.sas.SasVerificationService
import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType
@ -289,24 +287,18 @@ internal class DefaultCryptoService @Inject constructor(
outgoingRoomKeyRequestManager.stop()
}
override fun isCryptoEnabled(): Boolean {
// TODO Check that this test is correct
return olmDevice != null
}
// Aways enabled on RiotX
override fun isCryptoEnabled() = true
/**
* @return the Keys backup Service
*/
override fun getKeysBackupService(): KeysBackupService {
return keysBackup
}
override fun getKeysBackupService() = keysBackup
/**
* @return the SasVerificationService
*/
override fun getSasVerificationService(): SasVerificationService {
return sasVerificationService
}
override fun getSasVerificationService() = sasVerificationService
/**
* A sync response has been received

View file

@ -250,7 +250,7 @@ internal class MXOlmDevice @Inject constructor(
return null
}
Timber.v("## createInboundSession() : sessionId: " + olmSession.sessionIdentifier())
Timber.v("## createInboundSession() : sessionId: ${olmSession.sessionIdentifier()}")
try {
olmAccount!!.removeOneTimeKeys(olmSession)
@ -262,7 +262,7 @@ internal class MXOlmDevice @Inject constructor(
Timber.v("## createInboundSession() : ciphertext: $ciphertext")
try {
val sha256 = olmUtility!!.sha256(URLEncoder.encode(ciphertext, "utf-8"))
Timber.v("## createInboundSession() :ciphertext: SHA256:" + sha256)
Timber.v("## createInboundSession() :ciphertext: SHA256: $sha256")
} catch (e: Exception) {
Timber.e(e, "## createInboundSession() :ciphertext: cannot encode ciphertext")
}
@ -352,7 +352,7 @@ internal class MXOlmDevice @Inject constructor(
res["body"] = olmMessage.mCipherText
res["type"] = olmMessage.mType
} catch (e: Exception) {
Timber.e(e, "## encryptMessage() : failed " + e.message)
Timber.e(e, "## encryptMessage() : failed")
}
}
@ -384,7 +384,7 @@ internal class MXOlmDevice @Inject constructor(
olmSessionWrapper.onMessageReceived()
store.storeSession(olmSessionWrapper, theirDeviceIdentityKey)
} catch (e: Exception) {
Timber.e(e, "## decryptMessage() : decryptMessage failed " + e.message)
Timber.e(e, "## decryptMessage() : decryptMessage failed")
}
}
@ -425,7 +425,7 @@ internal class MXOlmDevice @Inject constructor(
outboundGroupSessionStore[session.sessionIdentifier()] = session
return session.sessionIdentifier()
} catch (e: Exception) {
Timber.e(e, "createOutboundGroupSession " + e.message)
Timber.e(e, "createOutboundGroupSession")
session?.releaseSession()
}
@ -444,7 +444,7 @@ internal class MXOlmDevice @Inject constructor(
try {
return outboundGroupSessionStore[sessionId]!!.sessionKey()
} catch (e: Exception) {
Timber.e(e, "## getSessionKey() : failed " + e.message)
Timber.e(e, "## getSessionKey() : failed")
}
}
@ -475,7 +475,7 @@ internal class MXOlmDevice @Inject constructor(
try {
return outboundGroupSessionStore[sessionId]!!.encryptMessage(payloadString)
} catch (e: Exception) {
Timber.e(e, "## encryptGroupMessage() : failed " + e.message)
Timber.e(e, "## encryptGroupMessage() : failed")
}
}
@ -583,7 +583,7 @@ internal class MXOlmDevice @Inject constructor(
try {
if (!TextUtils.equals(session.olmInboundGroupSession?.sessionIdentifier(), sessionId)) {
Timber.e("## importInboundGroupSession : ERROR: Mismatched group session ID from senderKey: " + senderKey!!)
Timber.e("## importInboundGroupSession : ERROR: Mismatched group session ID from senderKey: $senderKey")
if (session.olmInboundGroupSession != null) session.olmInboundGroupSession!!.releaseSession()
continue
}
@ -652,9 +652,8 @@ internal class MXOlmDevice @Inject constructor(
// Check that the room id matches the original one for the session. This stops
// the HS pretending a message was targeting a different room.
if (roomId == session.roomId) {
var decryptResult: OlmInboundGroupSession.DecryptMessageResult? = null
try {
decryptResult = session.olmInboundGroupSession!!.decryptMessage(body)
val decryptResult = try {
session.olmInboundGroupSession!!.decryptMessage(body)
} catch (e: OlmException) {
Timber.e(e, "## decryptGroupMessage () : decryptMessage failed")
throw MXCryptoError.OlmError(e)

View file

@ -76,7 +76,8 @@ internal class RoomDecryptorProvider @Inject constructor(
val alg = when (algorithm) {
MXCRYPTO_ALGORITHM_MEGOLM -> megolmDecryptionFactory.create().apply {
this.newSessionListener = object : NewSessionListener {
override fun onNewSession(rid: String?, senderKey: String, sessionId: String) {
override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) {
// PR reviewer: the parameter has been renamed so is now in conflict with the parameter of getOrCreateRoomDecryptor
newSessionListeners.forEach {
try {
it.onNewSession(roomId, senderKey, sessionId)

View file

@ -81,7 +81,7 @@ internal class MessageEncrypter @Inject constructor(private val credentials: Cre
payloadJson["recipient_keys"] = recipientsKeysMap
val payloadString = convertToUTF8(JsonCanonicalizer.getCanonicalJson(Map::class.java, payloadJson))
ciphertext[deviceKey] = olmDevice.encryptMessage(deviceKey, sessionId!!, payloadString!!)!!
ciphertext[deviceKey] = olmDevice.encryptMessage(deviceKey, sessionId!!, payloadString)!!
}
}

View file

@ -253,7 +253,7 @@ internal class MXMegolmEncryption(
// Get canonical Json from
val payloadString = convertToUTF8(JsonCanonicalizer.getCanonicalJson(Map::class.java, payloadJson))
val ciphertext = olmDevice.encryptGroupMessage(session.sessionId, payloadString!!)
val ciphertext = olmDevice.encryptGroupMessage(session.sessionId, payloadString)
val map = HashMap<String, Any>()
map["algorithm"] = MXCRYPTO_ALGORITHM_MEGOLM

View file

@ -63,6 +63,7 @@ internal class MXOlmDecryption(
}
// The message for myUser
@Suppress("UNCHECKED_CAST")
val message = messageAny as JsonDict
val decryptedPayload = decryptMessage(message, senderKey)
@ -72,10 +73,6 @@ internal class MXOlmDecryption(
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON)
}
val payloadString = convertFromUTF8(decryptedPayload)
if (payloadString == null) {
Timber.e("## decryptEvent() Failed to decrypt Olm event (id= ${event.eventId} from $senderKey")
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON)
}
val adapter = MoshiProvider.providesMoshi().adapter<JsonDict>(JSON_DICT_PARAMETERIZED_TYPE)
val payload = adapter.fromJson(payloadString)
@ -104,7 +101,8 @@ internal class MXOlmDecryption(
}
val recipientKeys = olmPayloadContent.recipient_keys ?: run {
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys' property; cannot prevent unknown-key attack")
Timber.e("## decryptEvent() : Olm event (id=${event.eventId}) contains no 'recipient_keys'" +
" property; cannot prevent unknown-key attack")
throw MXCryptoError.Base(MXCryptoError.ErrorType.MISSING_PROPERTY,
String.format(MXCryptoError.ERROR_MISSING_PROPERTY_REASON, "recipient_keys"))
}
@ -161,9 +159,9 @@ internal class MXOlmDecryption(
val messageBody = message["body"] as? String ?: return null
val messageType = when (val typeAsVoid = message["type"]) {
is Double -> typeAsVoid.toInt()
is Int -> typeAsVoid
is Long -> typeAsVoid.toInt()
else -> return null
is Int -> typeAsVoid
is Long -> typeAsVoid.toInt()
else -> return null
}
// Try each session in turn

View file

@ -103,10 +103,10 @@ object MXEncryptedAttachments {
ext = true,
key_ops = listOf("encrypt", "decrypt"),
kty = "oct",
k = base64ToBase64Url(Base64.encodeToString(key, Base64.DEFAULT))!!
k = base64ToBase64Url(Base64.encodeToString(key, Base64.DEFAULT))
),
iv = Base64.encodeToString(initVectorBytes, Base64.DEFAULT).replace("\n", "").replace("=", ""),
hashes = mapOf("sha256" to base64ToUnpaddedBase64(Base64.encodeToString(messageDigest.digest(), Base64.DEFAULT))!!),
hashes = mapOf("sha256" to base64ToUnpaddedBase64(Base64.encodeToString(messageDigest.digest(), Base64.DEFAULT))),
v = "v2"
),
encryptedByteArray = outStream.toByteArray()

View file

@ -31,6 +31,7 @@ import im.vector.matrix.android.api.listeners.StepProgressListener
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupService
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupStateListener
import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
import im.vector.matrix.android.internal.crypto.MXOlmDevice
import im.vector.matrix.android.internal.crypto.MegolmSessionData
@ -194,22 +195,23 @@ internal class KeysBackup @Inject constructor(
callback: MatrixCallback<KeysVersion>) {
val createKeysBackupVersionBody = CreateKeysBackupVersionBody()
createKeysBackupVersionBody.algorithm = keysBackupCreationInfo.algorithm
@Suppress("UNCHECKED_CAST")
createKeysBackupVersionBody.authData = MoshiProvider.providesMoshi().adapter(Map::class.java)
.fromJson(keysBackupCreationInfo.authData?.toJsonString()) as Map<String, Any>?
.fromJson(keysBackupCreationInfo.authData?.toJsonString() ?: "") as JsonDict?
keysBackupStateManager.state = KeysBackupState.Enabling
createKeysBackupVersionTask
.configureWith(createKeysBackupVersionBody) {
this.callback = object : MatrixCallback<KeysVersion> {
override fun onSuccess(info: KeysVersion) {
override fun onSuccess(data: KeysVersion) {
// Reset backup markers.
cryptoStore.resetBackupMarkers()
val keyBackupVersion = KeysVersionResult()
keyBackupVersion.algorithm = createKeysBackupVersionBody.algorithm
keyBackupVersion.authData = createKeysBackupVersionBody.authData
keyBackupVersion.version = info.version
keyBackupVersion.version = data.version
// We can consider that the server does not have keys yet
keyBackupVersion.count = 0
@ -217,7 +219,7 @@ internal class KeysBackup @Inject constructor(
enableKeysBackup(keyBackupVersion)
callback.onSuccess(info)
callback.onSuccess(data)
}
override fun onFailure(failure: Throwable) {
@ -275,7 +277,8 @@ internal class KeysBackup @Inject constructor(
val keysBackupData = cryptoStore.getKeysBackupData()
val totalNumberOfKeysServer = keysBackupData?.backupLastServerNumberOfKeys ?: -1
val hashServer = keysBackupData?.backupLastServerHash
// Not used for the moment
// val hashServer = keysBackupData?.backupLastServerHash
return when {
totalNumberOfKeysLocally < totalNumberOfKeysServer -> {
@ -414,7 +417,7 @@ internal class KeysBackup @Inject constructor(
olmDevice.verifySignature(fingerprint, authData.signalableJSONDictionary(), mySigs[keyId] as String)
isSignatureValid = true
} catch (e: OlmException) {
Timber.v("getKeysBackupTrust: Bad signature from device " + device.deviceId + " " + e.localizedMessage)
Timber.v(e, "getKeysBackupTrust: Bad signature from device ${device.deviceId}")
}
}
@ -484,6 +487,7 @@ internal class KeysBackup @Inject constructor(
val moshi = MoshiProvider.providesMoshi()
val adapter = moshi.adapter(Map::class.java)
@Suppress("UNCHECKED_CAST")
updateKeysBackupVersionBody.authData = adapter.fromJson(newMegolmBackupAuthData.toJsonString()) as Map<String, Any>?
updateKeysBackupVersionBody
@ -616,7 +620,7 @@ internal class KeysBackup @Inject constructor(
GlobalScope.launch(coroutineDispatchers.main) {
withContext(coroutineDispatchers.crypto) {
Try {
Try<OlmPkDecryption> {
// Check if the recovery is valid before going any further
if (!isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysVersionResult)) {
Timber.e("restoreKeysWithRecoveryKey: Invalid recovery key for this keys version")
@ -631,7 +635,7 @@ internal class KeysBackup @Inject constructor(
throw InvalidParameterException("Invalid recovery key")
}
decryption!!
decryption
}
}.fold(
{
@ -661,14 +665,12 @@ internal class KeysBackup @Inject constructor(
}
}
}
Timber.v("restoreKeysWithRecoveryKey: Decrypted " + sessionsData.size + " keys out of "
+ sessionsFromHsCount + " from the backup store on the homeserver")
Timber.v("restoreKeysWithRecoveryKey: Decrypted ${sessionsData.size} keys out of $sessionsFromHsCount from the backup store on the homeserver")
// Do not trigger a backup for them if they come from the backup version we are using
val backUp = keysVersionResult.version != keysBackupVersion?.version
if (backUp) {
Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up to backup version: "
+ keysBackupVersion?.version)
Timber.v("restoreKeysWithRecoveryKey: Those keys will be backed up to backup version: ${keysBackupVersion?.version}")
}
// Import them into the crypto store
@ -986,7 +988,7 @@ internal class KeysBackup @Inject constructor(
val versionInStore = cryptoStore.getKeyBackupVersion()
if (data.usable) {
Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: " + keyBackupVersion.version)
Timber.v("checkAndStartWithKeysBackupVersion: Found usable key backup. version: ${keyBackupVersion.version}")
// Check the version we used at the previous app run
if (versionInStore != null && versionInStore != keyBackupVersion.version) {
Timber.v(" -> clean the previously used version $versionInStore")
@ -996,7 +998,7 @@ internal class KeysBackup @Inject constructor(
Timber.v(" -> enabling key backups")
enableKeysBackup(keyBackupVersion)
} else {
Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: " + keyBackupVersion.version)
Timber.v("checkAndStartWithKeysBackupVersion: No usable key backup. version: ${keyBackupVersion.version}")
if (versionInStore != null) {
Timber.v(" -> disabling key backup")
resetKeysBackupData()
@ -1201,7 +1203,7 @@ internal class KeysBackup @Inject constructor(
// Get a chunk of keys to backup
val olmInboundGroupSessionWrappers = cryptoStore.inboundGroupSessionsToBackup(KEY_BACKUP_SEND_KEYS_MAX_COUNT)
Timber.v("backupKeys: 1 - " + olmInboundGroupSessionWrappers.size + " sessions to back up")
Timber.v("backupKeys: 1 - ${olmInboundGroupSessionWrappers.size} sessions to back up")
if (olmInboundGroupSessionWrappers.isEmpty()) {
// Backup is up to date

View file

@ -17,6 +17,7 @@
package im.vector.matrix.android.internal.crypto.keysbackup.model.rest
import com.squareup.moshi.Json
import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.internal.crypto.keysbackup.model.MegolmBackupAuthData
import im.vector.matrix.android.internal.di.MoshiProvider
@ -49,7 +50,7 @@ open class KeysAlgorithmAndData {
* algorithm-dependent data, for "m.megolm_backup.v1.curve25519-aes-sha2" see [im.vector.matrix.android.internal.crypto.keysbackup.MegolmBackupAuthData]
*/
@Json(name = "auth_data")
var authData: Map<String, Any>? = null
var authData: JsonDict? = null
/**
* Facility method to convert authData to a MegolmBackupAuthData object

View file

@ -103,6 +103,7 @@ data class MXKey(
val params = map[firstKey]
if (params != null) {
if (params["key"] is String) {
@Suppress("UNCHECKED_CAST")
return MXKey(
type = components[0],
keyId = components[1],

View file

@ -179,7 +179,7 @@ internal interface IMXCryptoStore {
* @param userId The user's id.
* @param devices A map from device id to 'MXDevice' object for the device.
*/
fun storeUserDevices(userId: String, devices: Map<String, MXDeviceInfo>)
fun storeUserDevices(userId: String, devices: Map<String, MXDeviceInfo>?)
/**
* Retrieve the known devices for a user.

View file

@ -98,6 +98,7 @@ fun <T> deserializeFromRealm(string: String?): T? {
val gzis = GZIPInputStream(bais)
val ois = ObjectInputStream(gzis)
@Suppress("UNCHECKED_CAST")
val result = ois.readObject() as T
ois.close()

View file

@ -209,10 +209,7 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati
?.getDeviceInfo()
}
override fun storeUserDevices(userId: String, devices: Map<String, MXDeviceInfo>) {
if (userId == null) {
return
}
override fun storeUserDevices(userId: String, devices: Map<String, MXDeviceInfo>?) {
doRealmTransaction(realmConfiguration) { realm ->
if (devices == null) {
// Remove the user
@ -281,7 +278,7 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati
try {
sessionIdentifier = olmSessionWrapper.olmSession.sessionIdentifier()
} catch (e: OlmException) {
Timber.e(e, "## storeSession() : sessionIdentifier failed " + e.message)
Timber.e(e, "## storeSession() : sessionIdentifier failed")
}
if (sessionIdentifier != null) {
@ -367,7 +364,7 @@ internal class RealmCryptoStore(private val realmConfiguration: RealmConfigurati
try {
sessionIdentifier = session.olmInboundGroupSession?.sessionIdentifier()
} catch (e: OlmException) {
Timber.e(e, "## storeInboundGroupSession() : sessionIdentifier failed " + e.message)
Timber.e(e, "## storeInboundGroupSession() : sessionIdentifier failed")
}
if (sessionIdentifier != null) {

View file

@ -61,7 +61,7 @@ internal object EventAnnotationsSummaryMapper {
it.lastEditTs
)
}
eventAnnotationsSummaryEntity.reactionsSummary = annotationsSummary.reactionsSummary?.let {
eventAnnotationsSummaryEntity.reactionsSummary = annotationsSummary.reactionsSummary.let {
RealmList<ReactionAggregatedSummaryEntity>().apply {
addAll(it.map {
ReactionAggregatedSummaryEntity(

View file

@ -48,16 +48,17 @@ internal object EventMapper {
}
fun map(eventEntity: EventEntity): Event {
val ud = if (eventEntity.unsignedData.isNullOrBlank()) {
null
} else {
try {
MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).fromJson(eventEntity.unsignedData)
} catch (t: JsonDataException) {
null
}
val ud = eventEntity.unsignedData
?.takeIf { it.isNotBlank() }
?.let {
try {
MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).fromJson(it)
} catch (t: JsonDataException) {
Timber.e(t, "Failed to parse UnsignedData")
null
}
}
}
return Event(
type = eventEntity.type,
eventId = eventEntity.eventId,
@ -79,7 +80,9 @@ internal object EventMapper {
}
}
//TODO get the full crypto error object
it.mCryptoError = eventEntity.decryptionErrorCode?.let { MXCryptoError.ErrorType.valueOf(it) }
it.mCryptoError = eventEntity.decryptionErrorCode?.let { errorCode ->
MXCryptoError.ErrorType.valueOf(errorCode)
}
}
}

View file

@ -58,7 +58,7 @@ internal class UserAgentHolder @Inject constructor(private val context: Context)
appName = appPackageName
}
} catch (e: Exception) {
Timber.e(e, "## initUserAgent() : failed " + e.message)
Timber.e(e, "## initUserAgent() : failed")
}
var systemUserAgent = System.getProperty("http.agent")

View file

@ -104,11 +104,11 @@ internal object CertUtil {
* Recursively checks the exception to see if it was caused by an
* UnrecognizedCertificateException
*
* @param e the throwable.
* @param root the throwable.
* @return The UnrecognizedCertificateException if exists, else null.
*/
fun getCertificateException(e: Throwable?): UnrecognizedCertificateException? {
var e = e
fun getCertificateException(root: Throwable?): UnrecognizedCertificateException? {
var e = root
var i = 0 // Just in case there is a getCause loop
while (e != null && i < 10) {
if (e is UnrecognizedCertificateException) {
@ -140,7 +140,7 @@ internal object CertUtil {
try {
tf = TrustManagerFactory.getInstance("PKIX")
} catch (e: Exception) {
Timber.e(e, "## newPinnedSSLSocketFactory() : TrustManagerFactory.getInstance failed " + e.message)
Timber.e(e, "## newPinnedSSLSocketFactory() : TrustManagerFactory.getInstance failed")
}
// it doesn't exist, use the default one.
@ -148,7 +148,7 @@ internal object CertUtil {
try {
tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
} catch (e: Exception) {
Timber.e(e, "## addRule : onBingRuleUpdateFailure failed " + e.message)
Timber.e(e, "## addRule : onBingRuleUpdateFailure failed")
}
}
@ -202,7 +202,7 @@ internal object CertUtil {
try {
for (cert in session.peerCertificates) {
for (allowedFingerprint in trustedFingerprints) {
if (allowedFingerprint != null && cert is X509Certificate && allowedFingerprint.matchesCert(cert)) {
if (cert is X509Certificate && allowedFingerprint.matchesCert(cert)) {
return@HostnameVerifier true
}
}
@ -235,6 +235,7 @@ internal object CertUtil {
builder.cipherSuites(*tlsCipherSuites.toTypedArray())
}
@Suppress("DEPRECATION")
builder.supportsTlsExtensions(hsConfig.shouldAcceptTlsExtensions)
val list = ArrayList<ConnectionSpec>()
list.add(builder.build())

View file

@ -31,54 +31,50 @@ import javax.net.ssl.X509TrustManager
* @param defaultTrustManager Optional trust manager to fall back on if cert does not match
* any of the fingerprints. Can be null.
*/
internal class PinnedTrustManager(private val mFingerprints: List<Fingerprint>?,
private val mDefaultTrustManager: X509TrustManager?) : X509TrustManager {
internal class PinnedTrustManager(private val fingerprints: List<Fingerprint>?,
private val defaultTrustManager: X509TrustManager?) : X509TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate>, s: String) {
try {
if (mDefaultTrustManager != null) {
mDefaultTrustManager.checkClientTrusted(
chain, s
)
if (defaultTrustManager != null) {
defaultTrustManager.checkClientTrusted(chain, s)
return
}
} catch (e: CertificateException) {
// If there is an exception we fall back to checking fingerprints
if (mFingerprints == null || mFingerprints.isEmpty()) {
if (fingerprints == null || fingerprints.isEmpty()) {
throw UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.cause)
}
}
checkTrusted("client", chain)
checkTrusted(chain)
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate>, s: String) {
try {
if (mDefaultTrustManager != null) {
mDefaultTrustManager.checkServerTrusted(
chain, s
)
if (defaultTrustManager != null) {
defaultTrustManager.checkServerTrusted(chain, s)
return
}
} catch (e: CertificateException) {
// If there is an exception we fall back to checking fingerprints
if (mFingerprints == null || mFingerprints.isEmpty()) {
if (fingerprints == null || fingerprints.isEmpty()) {
throw UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.cause)
}
}
checkTrusted("server", chain)
checkTrusted(chain)
}
@Throws(CertificateException::class)
private fun checkTrusted(type: String, chain: Array<X509Certificate>) {
private fun checkTrusted(chain: Array<X509Certificate>) {
val cert = chain[0]
var found = false
if (mFingerprints != null) {
for (allowedFingerprint in mFingerprints) {
if (fingerprints != null) {
for (allowedFingerprint in fingerprints) {
if (allowedFingerprint.matchesCert(cert)) {
found = true
break

View file

@ -22,9 +22,13 @@ import im.vector.matrix.android.internal.di.Authenticated
import im.vector.matrix.android.internal.network.ProgressRequestBody
import im.vector.matrix.android.internal.network.awaitResponse
import im.vector.matrix.android.internal.network.toFailure
import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File
import java.io.IOException
import javax.inject.Inject
@ -32,8 +36,8 @@ import javax.inject.Inject
internal class FileUploader @Inject constructor(@Authenticated
private val okHttpClient: OkHttpClient,
private val sessionParams: SessionParams,
private val moshi: Moshi) {
sessionParams: SessionParams,
moshi: Moshi) {
private val uploadUrl = DefaultContentUrlResolver.getUploadUrl(sessionParams.homeServerConnectionConfig)
private val responseAdapter = moshi.adapter(ContentUploadResponse::class.java)
@ -43,7 +47,7 @@ internal class FileUploader @Inject constructor(@Authenticated
filename: String?,
mimeType: String,
progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse {
val uploadBody = RequestBody.create(mimeType.toMediaTypeOrNull(), file)
val uploadBody = file.asRequestBody(mimeType.toMediaTypeOrNull())
return upload(uploadBody, filename, progressListener)
}
@ -52,7 +56,7 @@ internal class FileUploader @Inject constructor(@Authenticated
filename: String?,
mimeType: String,
progressListener: ProgressRequestBody.Listener? = null): ContentUploadResponse {
val uploadBody = RequestBody.create(mimeType.toMediaTypeOrNull(), byteArray)
val uploadBody = byteArray.toRequestBody(mimeType.toMediaTypeOrNull())
return upload(uploadBody, filename, progressListener)
}

View file

@ -23,7 +23,6 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.query.types
import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import io.realm.OrderedCollectionChangeSet
@ -37,7 +36,6 @@ import javax.inject.Inject
* As it will actually delete the content, it should be called last in the list of listener.
*/
internal class EventsPruner @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
@UserId private val userId: String,
private val pruneEventTask: PruneEventTask,
private val taskExecutor: TaskExecutor) :
RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
@ -52,10 +50,7 @@ internal class EventsPruner @Inject constructor(@SessionDatabase realmConfigurat
.mapNotNull { results[it]?.asDomain() }
.toList()
val params = PruneEventTask.Params(
insertedDomains,
userId
)
val params = PruneEventTask.Params(insertedDomains)
pruneEventTask.configureWith(params).executeBy(taskExecutor)
}

View file

@ -38,8 +38,7 @@ import javax.inject.Inject
internal interface PruneEventTask : Task<PruneEventTask.Params, Unit> {
data class Params(
val redactionEvents: List<Event>,
val userId: String
val redactionEvents: List<Event>
)
}
@ -49,19 +48,19 @@ internal class DefaultPruneEventTask @Inject constructor(private val monarchy: M
override suspend fun execute(params: PruneEventTask.Params) {
monarchy.awaitTransaction { realm ->
params.redactionEvents.forEach { event ->
pruneEvent(realm, event, params.userId)
pruneEvent(realm, event)
}
}
}
private fun pruneEvent(realm: Realm, redactionEvent: Event, userId: String) {
private fun pruneEvent(realm: Realm, redactionEvent: Event) {
if (redactionEvent.redacts.isNullOrBlank()) {
return
}
val redactionEventEntity = EventEntity.where(realm, eventId = redactionEvent.eventId
?: "").findFirst()
?: return
// Check that we know this event
EventEntity.where(realm, eventId = redactionEvent.eventId ?: "").findFirst() ?: return
val isLocalEcho = LocalEchoEventFactory.isLocalEchoId(redactionEvent.eventId ?: "")
Timber.v("Redact event for ${redactionEvent.redacts} localEcho=$isLocalEcho")

View file

@ -71,7 +71,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
localEchoUpdater.updateSendState(localEvent.eventId, SendState.ENCRYPTING)
val localMutableContent = HashMap(localEvent.content)
val localMutableContent = localEvent.content?.toMutableMap() ?: mutableMapOf()
params.keepKeys?.forEach {
localMutableContent.remove(it)
}

View file

@ -160,7 +160,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
reaction
)
)
val localId = dummyEventId(roomId)
val localId = dummyEventId()
return Event(
roomId = roomId,
originServerTs = dummyOriginServerTs(),
@ -266,7 +266,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
}
private fun createEvent(roomId: String, content: Any? = null): Event {
val localID = dummyEventId(roomId)
val localID = dummyEventId()
return Event(
roomId = roomId,
originServerTs = dummyOriginServerTs(),
@ -282,7 +282,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
return System.currentTimeMillis()
}
private fun dummyEventId(roomId: String): String {
private fun dummyEventId(): String {
return "$LOCAL_ID_PREFIX${UUID.randomUUID()}"
}
@ -384,7 +384,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
}
*/
fun createRedactEvent(roomId: String, eventId: String, reason: String?): Event {
val localID = dummyEventId(roomId)
val localID = dummyEventId()
return Event(
roomId = roomId,
originServerTs = dummyOriginServerTs(),
@ -398,7 +398,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
}
fun saveLocalEcho(monarchy: Monarchy, event: Event) {
if (event.roomId == null) throw IllegalStateException("Your event should have a roomId")
checkNotNull(event.roomId) { "Your event should have a roomId" }
monarchy.writeAsync { realm ->
val roomEntity = RoomEntity.where(realm, roomId = event.roomId).findFirst()
?: return@writeAsync

View file

@ -71,7 +71,7 @@ internal class DefaultTimelineService @AssistedInject constructor(@Assisted priv
return monarchy
.fetchCopyMap({
TimelineEventEntity.where(it, roomId = roomId, eventId = eventId).findFirst()
}, { entity, realm ->
}, { entity, _ ->
timelineEventMapper.map(entity)
})
}

View file

@ -14,6 +14,8 @@
* limitations under the License.
*/
@file:Suppress("DEPRECATION")
package im.vector.matrix.android.internal.session.securestorage
import android.content.Context
@ -65,7 +67,7 @@ import javax.security.auth.x500.X500Principal
* //This can be stored anywhere e.g. encoded in b64 and stored in preference for example
*
* //to get back the secret, just call
* val kDecripted = SecretStoringUtils.loadSecureSecret(KEncrypted!!, "myAlias", context)
* val kDecrypted = SecretStoringUtils.loadSecureSecret(KEncrypted!!, "myAlias", context)
* </code>
*
* You can also just use this utility to store a secret key, and use any encryption algorithm that you want.
@ -169,7 +171,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
}
/*
Symetric Key Generation is only available in M, so before M the idea is to:
Symmetric Key Generation is only available in M, so before M the idea is to:
- Generate a pair of RSA keys;
- Generate a random AES key;
- Encrypt the AES key using the RSA public key;
@ -194,7 +196,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
.setStartDate(start.time)
.setEndDate(end.time)
.build()
KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEY_STORE).run {
KeyPairGenerator.getInstance("RSA" /*KeyProperties.KEY_ALGORITHM_RSA*/, ANDROID_KEY_STORE).run {
initialize(spec)
generateKeyPair()
}
@ -230,7 +232,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun encryptStringK(text: String, keyAlias: String): ByteArray? {
//we generate a random symetric key
//we generate a random symmetric key
val key = ByteArray(16)
secureRandom.nextBytes(key)
val sKey = SecretKeySpec(key, "AES")
@ -307,7 +309,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
ObjectOutputStream(bos1).use {
it.writeObject(writeObject)
}
//Have to do it like that if i encapsulate the outputstream, the cipher could fail saying reuse IV
//Have to do it like that if i encapsulate the output stream, the cipher could fail saying reuse IV
val doFinal = cipher.doFinal(bos1.toByteArray())
output.write(FORMAT_API_M.toInt())
output.write(iv.size)
@ -317,7 +319,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
@RequiresApi(Build.VERSION_CODES.KITKAT)
private fun saveSecureObjectK(keyAlias: String, output: OutputStream, writeObject: Any) {
//we generate a random symetric key
//we generate a random symmetric key
val key = ByteArray(16)
secureRandom.nextBytes(key)
val sKey = SecretKeySpec(key, "AES")
@ -360,7 +362,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
ObjectOutputStream(bos1).use {
it.writeObject(writeObject)
}
//Have to do it like that if i encapsulate the outputstream, the cipher could fail saying reuse IV
//Have to do it like that if i encapsulate the output stream, the cipher could fail saying reuse IV
val doFinal = cipher.doFinal(bos1.toByteArray())
output.write(FORMAT_2.toInt())
@ -405,6 +407,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
CipherInputStream(inputStream, cipher).use { cipherInputStream ->
ObjectInputStream(cipherInputStream).use {
val readObject = it.readObject()
@Suppress("UNCHECKED_CAST")
return readObject as? T
}
}
@ -428,6 +431,7 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
CipherInputStream(encIS, cipher).use { cipherInputStream ->
ObjectInputStream(cipherInputStream).use {
val readObject = it.readObject()
@Suppress("UNCHECKED_CAST")
return readObject as? T
}
}
@ -449,8 +453,9 @@ internal class SecretStoringUtils @Inject constructor(private val context: Conte
val encIS = ByteArrayInputStream(encrypted)
CipherInputStream(encIS, cipher).use {
ObjectInputStream(it).use {
val readObject = it.readObject()
ObjectInputStream(it).use { ois ->
val readObject = ois.readObject()
@Suppress("UNCHECKED_CAST")
return readObject as? T
}
}

View file

@ -24,13 +24,8 @@ import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.tag.RoomTagContent
import im.vector.matrix.android.internal.session.room.read.FullyReadContent
import im.vector.matrix.android.internal.database.helper.add
import im.vector.matrix.android.internal.database.helper.addOrUpdate
import im.vector.matrix.android.internal.database.helper.addStateEvent
import im.vector.matrix.android.internal.database.helper.lastStateIndex
import im.vector.matrix.android.internal.database.helper.updateSenderDataFor
import im.vector.matrix.android.internal.crypto.DefaultCryptoService
import im.vector.matrix.android.internal.database.helper.*
import im.vector.matrix.android.internal.database.model.ChunkEntity
import im.vector.matrix.android.internal.database.model.EventEntityFields
import im.vector.matrix.android.internal.database.model.RoomEntity
@ -42,12 +37,9 @@ import im.vector.matrix.android.internal.session.mapWithProgress
import im.vector.matrix.android.internal.session.notification.DefaultPushRuleService
import im.vector.matrix.android.internal.session.notification.ProcessEventForPushTask
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.read.FullyReadContent
import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection
import im.vector.matrix.android.internal.session.sync.model.InvitedRoomSync
import im.vector.matrix.android.internal.session.sync.model.RoomSync
import im.vector.matrix.android.internal.session.sync.model.RoomSyncAccountData
import im.vector.matrix.android.internal.session.sync.model.RoomSyncEphemeral
import im.vector.matrix.android.internal.session.sync.model.RoomsSyncResponse
import im.vector.matrix.android.internal.session.sync.model.*
import im.vector.matrix.android.internal.session.user.UserEntityFactory
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
@ -247,11 +239,11 @@ internal class RoomSyncHandler @Inject constructor(private val monarchy: Monarch
private fun handleEphemeral(realm: Realm,
roomId: String,
ephemeral: RoomSyncEphemeral,
isInitalSync: Boolean) {
isInitialSync: Boolean) {
for (event in ephemeral.events) {
if (event.type != EventType.RECEIPT) continue
val readReceiptContent = event.content as? ReadReceiptContent ?: continue
readReceiptHandler.handle(realm, roomId, readReceiptContent, isInitalSync)
readReceiptHandler.handle(realm, roomId, readReceiptContent, isInitialSync)
}
}

View file

@ -14,6 +14,8 @@
* limitations under the License.
*/
@file:Suppress("DEPRECATION")
package im.vector.matrix.android.internal.util
import android.content.Context
@ -34,7 +36,7 @@ import java.security.*
import java.security.cert.CertificateException
import java.security.spec.AlgorithmParameterSpec
import java.security.spec.RSAKeyGenParameterSpec
import java.util.Calendar
import java.util.*
import java.util.zip.GZIPOutputStream
import javax.crypto.*
import javax.crypto.spec.GCMParameterSpec
@ -244,9 +246,6 @@ object CompatUtil {
}
val keyAndVersion = getAesGcmLocalProtectionKey(context)
if (keyAndVersion == null || keyAndVersion.secretKey == null) {
throw KeyStoreException()
}
val cipher = Cipher.getInstance(AES_GCM_CIPHER_TYPE)
val iv: ByteArray
@ -261,7 +260,7 @@ object CompatUtil {
}
if (iv.size != AES_GCM_IV_LENGTH) {
Timber.e(TAG, "Invalid IV length " + iv.size)
Timber.e(TAG, "Invalid IV length ${iv.size}")
return null
}
@ -307,16 +306,11 @@ object CompatUtil {
val cipher = Cipher.getInstance(AES_GCM_CIPHER_TYPE)
val keyAndVersion = getAesGcmLocalProtectionKey(context)
if (keyAndVersion == null || keyAndVersion.secretKey == null) {
throw KeyStoreException()
}
val spec: AlgorithmParameterSpec
if (keyAndVersion.androidVersionWhenTheKeyHasBeenGenerated >= Build.VERSION_CODES.M) {
spec = GCMParameterSpec(AES_GCM_KEY_SIZE_IN_BITS, iv)
val spec: AlgorithmParameterSpec = if (keyAndVersion.androidVersionWhenTheKeyHasBeenGenerated >= Build.VERSION_CODES.M) {
GCMParameterSpec(AES_GCM_KEY_SIZE_IN_BITS, iv)
} else {
spec = IvParameterSpec(iv)
IvParameterSpec(iv)
}
cipher.init(Cipher.DECRYPT_MODE, keyAndVersion.secretKey, spec)

View file

@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.util
import im.vector.matrix.android.api.MatrixPatterns
import timber.log.Timber
import java.util.*
/**
* Convert a string to an UTF8 String
@ -25,13 +26,13 @@ import timber.log.Timber
* @param s the string to convert
* @return the utf-8 string
*/
fun convertToUTF8(s: String): String? {
fun convertToUTF8(s: String): String {
return try {
val bytes = s.toByteArray(Charsets.UTF_8)
String(bytes)
} catch (e: Exception) {
Timber.e(e, "## convertToUTF8() failed")
null
s
}
}
@ -41,13 +42,13 @@ fun convertToUTF8(s: String): String? {
* @param s the string to convert
* @return the utf-16 string
*/
fun convertFromUTF8(s: String): String? {
fun convertFromUTF8(s: String): String {
return try {
val bytes = s.toByteArray()
String(bytes, Charsets.UTF_8)
} catch (e: Exception) {
Timber.e(e, "## convertFromUTF8() failed")
null
s
}
}
@ -55,5 +56,5 @@ fun String?.firstLetterOfDisplayName(): String {
if (this.isNullOrEmpty()) return ""
val isUserId = MatrixPatterns.isUserId(this)
val firstLetterIndex = if (isUserId) 1 else 0
return this[firstLetterIndex].toString().toUpperCase()
return this[firstLetterIndex].toString().toUpperCase(Locale.ROOT)
}