Skip to content
Snippets Groups Projects
Commit cb445bd6 authored by Taras's avatar Taras
Browse files

Add bcrypt key generation

parent e291c34d
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,8 @@ const val MXCRYPTO_ALGORITHM_MEGOLM = "m.megolm.v1.aes-sha2"
*/
const val MXCRYPTO_ALGORITHM_MEGOLM_BACKUP = "m.megolm_backup.v1.curve25519-aes-sha2"
const val BCRYPT_ALGORITHM_BACKUP = "m.bcrypt"
/**
* Secured Shared Storage algorithm constant.
*/
......
......@@ -118,6 +118,9 @@ interface KeysBackupService {
progressListener: ProgressListener?,
callback: MatrixCallback<MegolmBackupCreationInfo>)
fun prepareBcryptKeysBackupVersion(userName:String, password: String,
callback: MatrixCallback<MegolmBackupCreationInfo>)
/**
* Delete a keys backup version. It will delete all backed up keys on the server, and the backup itself.
* If we are backing up to this version. Backup will be stopped.
......
package org.matrix.android.sdk.internal.crypto.keysbackup
import at.favre.lib.crypto.bcrypt.BCrypt
import java.security.MessageDigest
internal object BCryptManager {
private const val iterations = 14
private const val saltLength = 16
fun generateBcryptPrivateKeyWithPassword(
userName: String,
password: String
): GeneratePrivateKeyResult {
val salt = userName.sha256().substring(0, saltLength).toByteArray()
val privateKey = BCrypt.withDefaults().hash(iterations, salt, password.toByteArray())
return GeneratePrivateKeyResult(privateKey, salt.toString(), iterations)
}
private fun String.sha256(): String = MessageDigest
.getInstance("SHA-256")
.digest(this.toByteArray())
.fold("") { str, it -> str + "%02x".format(it) }
}
\ No newline at end of file
......@@ -28,6 +28,7 @@ import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.crypto.BCRYPT_ALGORITHM_BACKUP
import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixError
......@@ -233,6 +234,57 @@ internal class DefaultKeysBackupService @Inject constructor(
}
}
override fun prepareBcryptKeysBackupVersion(userName:String, password: String,
callback: MatrixCallback<MegolmBackupCreationInfo>) {
cryptoCoroutineScope.launch(coroutineDispatchers.io) {
try {
val generatePrivateKeyResult = BCryptManager.generateBcryptPrivateKeyWithPassword(userName,password)
val signalableBackupAuthData = SignalableMegolmBackupAuthData(
publicKey = generatePrivateKeyResult.privateKey.toString(),
privateKeySalt = generatePrivateKeyResult.salt,
privateKeyIterations = generatePrivateKeyResult.iterations
)
val canonicalJson = JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableBackupAuthData.signalableJSONDictionary())
val signatures = mutableMapOf<String, MutableMap<String, String>>()
val deviceSignature = objectSigner.signObject(canonicalJson)
deviceSignature.forEach { (userID, content) ->
signatures[userID] = content.toMutableMap()
}
// If we have cross signing add signature, will throw if cross signing not properly configured
try {
val crossSign = crossSigningOlm.signObject(CrossSigningOlm.KeyType.MASTER, canonicalJson)
signatures[credentials.userId]?.putAll(crossSign)
} catch (failure: Throwable) {
// ignore and log
Timber.w(failure, "prepareKeysBackupVersion: failed to sign with cross signing keys")
}
val signedBackupAuthData = MegolmBackupAuthData(
publicKey = signalableBackupAuthData.publicKey,
privateKeySalt = signalableBackupAuthData.privateKeySalt,
privateKeyIterations = signalableBackupAuthData.privateKeyIterations,
signatures = signatures
)
val creationInfo = MegolmBackupCreationInfo(
algorithm = BCRYPT_ALGORITHM_BACKUP,
authData = signedBackupAuthData,
recoveryKey = generatePrivateKeyResult.privateKey.toString()
)
uiHandler.post {
callback.onSuccess(creationInfo)
}
} catch (failure: Throwable) {
uiHandler.post {
callback.onFailure(failure)
}
}
}
}
override fun createKeysBackupVersion(keysBackupCreationInfo: MegolmBackupCreationInfo,
callback: MatrixCallback<KeysVersion>) {
@Suppress("UNCHECKED_CAST")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment