Skip to content

Commit 0313925

Browse files
Merge pull request #261 from smswithoutborders/dev
Dev
2 parents 4a4dbca + 95bf8e5 commit 0313925

33 files changed

Lines changed: 607 additions & 202 deletions

.idea/vcs.xml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ dependencies {
192192
// implementation project(':lib_smsmms_android:lib_smsmms_android')
193193
// implementation project(':lib_image_android:app')
194194
implementation 'com.github.smswithoutborders:lib_image_android:3275ac7'
195-
implementation 'com.github.smswithoutborders:lib_smsmms_android:e906520'
195+
implementation 'com.github.smswithoutborders:lib_smsmms_android:91141a5'
196196

197197
implementation libs.androidx.appcompat
198198
implementation libs.material
@@ -362,7 +362,6 @@ dependencies {
362362
implementation(libs.coil.compose)
363363
implementation(libs.coil.network.okhttp)
364364

365-
implementation libs.play.services.safetynet
366365
coreLibraryDesugaring libs.desugar.jdk.libs
367366
}
368367

app/src/main/java/com/example/sw0b_001/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ class MainActivity : AppCompatActivity() {
368368
val otpCodeNav: OTPCodeScreen = backEntry.toRoute()
369369
OtpCodeVerificationView(
370370
navController = navController,
371+
email = otpCodeNav.email,
371372
loginSignupPhoneNumber = otpCodeNav.loginSignupPhoneNumber,
372373
loginSignupPassword = otpCodeNav.loginSignupPassword,
373374
countryCode = otpCodeNav.countryCode,

app/src/main/java/com/example/sw0b_001/data/Cryptography.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,23 @@ object Cryptography {
2828
}
2929
}
3030

31-
fun generateKey(context: Context, keystoreAlias: String): ByteArray {
31+
fun generateKey(): Pair<ByteArray, ByteArray> {
32+
val libSigCurve25519 = SecurityCurve25519()
33+
val publicKey = libSigCurve25519.generateKey()
34+
return Pair(publicKey,libSigCurve25519.privateKey)
35+
}
36+
37+
fun generateKey(
38+
context: Context,
39+
keystoreAlias: String,
40+
): ByteArray {
3241
val libSigCurve25519 = SecurityCurve25519()
3342
val publicKey = libSigCurve25519.generateKey()
3443
val encryptionPublicKey = SecurityRSA.generateKeyPair(keystoreAlias, 2048)
3544
val privateKeyCipherText = SecurityRSA.encrypt(encryptionPublicKey,
3645
libSigCurve25519.privateKey)
37-
secureStorePrivateKey(context, keystoreAlias, privateKeyCipherText)
46+
secureStorePrivateKey(context, keystoreAlias,
47+
privateKeyCipherText)
3848
return publicKey
3949
}
4050

@@ -57,6 +67,11 @@ object Cryptography {
5767
return SecurityRSA.decrypt(keypair.private, cipherPrivateKey)
5868
}
5969

70+
fun calculateSharedSecret(publicKey: ByteArray, privateKey: ByteArray): ByteArray {
71+
val libSigCurve25519 = SecurityCurve25519(privateKey)
72+
return libSigCurve25519.calculateSharedSecret(publicKey)
73+
}
74+
6075
fun calculateSharedSecret(context: Context, keystoreAlias: String, publicKey: ByteArray): ByteArray {
6176
val privateKey = fetchPrivateKey(context, keystoreAlias)
6277
val libSigCurve25519 = SecurityCurve25519(privateKey)

app/src/main/java/com/example/sw0b_001/data/PayloadEncryptionComposeDecomposeInit.kt

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.sw0b_001.data
22

3+
import android.R.id.message
34
import android.content.Context
45
import android.content.Intent
56
import android.util.Base64
@@ -79,9 +80,10 @@ object PayloadEncryptionComposeDecomposeInit {
7980
state: States,
8081
content: ByteArray,
8182
ad: ByteArray,
83+
sk: ByteArray? = null,
8284
): Pair<Headers, ByteArray> {
8385
if(state.DHs == null) {
84-
val sk = Publishers.fetchPublisherSharedKey(context)
86+
val sk = sk ?: Publishers.fetchPublisherSharedKey(context)
8587
Ratchets.ratchetInitAlice(state, sk, ad)
8688
}
8789

@@ -181,6 +183,7 @@ object PayloadEncryptionComposeDecomposeInit {
181183
languageCode: String = "en",
182184
smsTransmission: Boolean = true,
183185
isLoggedIn: Boolean = true,
186+
privateKey: ByteArray? = null,
184187
onSuccessRunnable: (EncryptedContent) -> Unit? = {}
185188
): ByteArray {
186189
val states = Datastore.getDatastore(context).ratchetStatesDAO().fetch()
@@ -195,9 +198,17 @@ object PayloadEncryptionComposeDecomposeInit {
195198
States()
196199
}
197200

198-
val (header, cipherText) = encryptPayload(context, state, content, ad)
201+
val (header, cipherText) = encryptPayload(context, state, content, ad,
202+
when(privateKey != null) {
203+
true -> Cryptography.calculateSharedSecret(ad, privateKey)
204+
else -> null
205+
}
206+
)
207+
208+
if(privateKey == null) {
209+
saveState(context,state, states.firstOrNull()?.id)
210+
}
199211

200-
saveState(context,state, states.firstOrNull()?.id)
201212
val message = saveContent(
202213
context = context,
203214
content = content,
@@ -226,10 +237,9 @@ object PayloadEncryptionComposeDecomposeInit {
226237
languageCode = languageCode.encodeToByteArray(),
227238
)
228239

229-
val gatewayClient = context.settingsGetDefaultGatewayClients
230-
if(gatewayClient == null) {
240+
val gatewayClient =
241+
context.settingsGetDefaultGatewayClients ?:
231242
throw Exception("No default Gateway client")
232-
}
233243

234244
if (smsTransmission) {
235245
sendSms(
@@ -252,7 +262,7 @@ object PayloadEncryptionComposeDecomposeInit {
252262
platformShortcode: Byte,
253263
languageCode: ByteArray,
254264
): String {
255-
val deviceIDBytes = if (!context.settingsGetUseDeviceId) {
265+
val deviceIDBytes = if (context.settingsGetUseDeviceId) {
256266
Vaults.fetchDeviceId(context) ?: byteArrayOf()
257267
} else {
258268
byteArrayOf()

app/src/main/java/com/example/sw0b_001/data/Publishers.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,16 @@ class Publishers(val context: Context) {
223223
Base64.DEFAULT)
224224
}
225225

226-
fun fetchPublisherSharedKey(context: Context, publicKey: ByteArray? = null) : ByteArray {
226+
fun fetchPublisherSharedKey(
227+
context: Context,
228+
publicKey: ByteArray? = null,
229+
) : ByteArray {
227230
val pubKey = publicKey ?: fetchPublisherPublicKey(context)
228-
return Cryptography.calculateSharedSecret(context, PUBLISHER_ID_KEYSTORE_ALIAS,
229-
pubKey!!)
231+
return Cryptography.calculateSharedSecret(
232+
context,
233+
PUBLISHER_ID_KEYSTORE_ALIAS,
234+
pubKey!!
235+
)
230236
}
231237

232238
fun storeArtifacts(

app/src/main/java/com/example/sw0b_001/data/Vaults.kt

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.sw0b_001.data
22

3+
import android.R.attr.phoneNumber
34
import android.content.Context
45
import android.util.Base64
56
import android.util.Log
@@ -23,6 +24,9 @@ import java.security.DigestException
2324
import java.security.MessageDigest
2425
import androidx.core.content.edit
2526
import com.example.sw0b_001.data.Publishers.Companion.PUBLISHER_ATTRIBUTE_FILES
27+
import com.example.sw0b_001.data.Publishers.Companion.storeArtifacts
28+
import com.example.sw0b_001.extensions.context.Settings
29+
import com.example.sw0b_001.extensions.context.settingsSetIsEmailLogin
2630

2731
class Vaults(val context: Context) {
2832
private val DEVICE_ID_KEYSTORE_ALIAS = "DEVICE_ID_KEYSTORE_ALIAS"
@@ -108,13 +112,16 @@ class Vaults(val context: Context) {
108112
}
109113
}
110114

111-
private fun processVaultArtifacts(context: Context,
112-
encodedLlt: String,
113-
deviceIdPubKey: String,
114-
publisherPubKey: String,
115-
phoneNumber: String,
116-
clientDeviceIDPubKey: ByteArray,
117-
clientPublisherPubKey: ByteArray) {
115+
private fun processVaultArtifacts(
116+
context: Context,
117+
encodedLlt: String,
118+
deviceIdPubKey: String,
119+
publisherPubKey: String,
120+
authValue: String,
121+
clientDeviceIDPubKey: ByteArray,
122+
clientPublisherPubKey: ByteArray,
123+
isEmailLogin: Boolean,
124+
) {
118125
val deviceIdSharedKey = Cryptography.calculateSharedSecret(
119126
context,
120127
DEVICE_ID_KEYSTORE_ALIAS,
@@ -126,10 +133,11 @@ class Vaults(val context: Context) {
126133

127134
val deviceId = getDeviceID(
128135
deviceIdSharedKey,
129-
phoneNumber,
136+
authValue,
130137
clientDeviceIDPubKey
131138
)
132139

140+
context.settingsSetIsEmailLogin(isEmailLogin)
133141
storeArtifacts(context, llt, deviceId, clientDeviceIDPubKey)
134142
Publishers.storeArtifacts(context, publisherPubKey,
135143
Base64.encodeToString(clientPublisherPubKey,
@@ -143,6 +151,7 @@ class Vaults(val context: Context) {
143151
fun createEntity(
144152
context: Context,
145153
phoneNumber: String,
154+
email: String,
146155
countryCode: String,
147156
password: String,
148157
recaptchaToken: String,
@@ -161,7 +170,8 @@ class Vaults(val context: Context) {
161170
setPassword(password)
162171
setClientPublishPubKey(Base64.encodeToString(publishPubKey, Base64.DEFAULT))
163172
setClientDeviceIdPubKey(Base64.encodeToString(deviceIdPubKey, Base64.DEFAULT))
164-
setRecaptchaToken(recaptchaToken)
173+
setCaptchaToken(recaptchaToken)
174+
setEmailAddress(email)
165175
}.build()
166176

167177
val response = entityStub.createEntity(createEntityRequest1)
@@ -171,15 +181,18 @@ class Vaults(val context: Context) {
171181
response.longLivedToken,
172182
response.serverDeviceIdPubKey,
173183
response.serverPublishPubKey,
174-
phoneNumber,
175-
deviceIdPubKey, publishPubKey)
184+
email.ifEmpty { phoneNumber },
185+
deviceIdPubKey, publishPubKey,
186+
email.isNotEmpty(),
187+
)
176188
}
177189
return response
178190
}
179191

180192
fun authenticateEntity(
181193
context: Context,
182194
phoneNumber: String,
195+
email: String,
183196
password: String,
184197
recaptchaToken: String,
185198
ownershipResponse: String = ""
@@ -197,7 +210,8 @@ class Vaults(val context: Context) {
197210
Base64.DEFAULT))
198211
setClientDeviceIdPubKey(Base64.encodeToString(deviceIdPubKey,
199212
Base64.DEFAULT))
200-
setRecaptchaToken(recaptchaToken)
213+
setCaptchaToken(recaptchaToken)
214+
setEmailAddress(email)
201215

202216
if(ownershipResponse.isNotBlank()) {
203217
setOwnershipProofResponse(ownershipResponse)
@@ -215,15 +229,18 @@ class Vaults(val context: Context) {
215229
response.longLivedToken,
216230
response.serverDeviceIdPubKey,
217231
response.serverPublishPubKey,
218-
phoneNumber,
219-
deviceIdPubKey, publishPubKey)
232+
email.ifEmpty { phoneNumber },
233+
deviceIdPubKey, publishPubKey,
234+
email.isNotEmpty(),
235+
)
220236
}
221237
return response
222238
}
223239

224240
fun recoverEntityPassword(
225241
context: Context,
226242
phoneNumber: String,
243+
email: String,
227244
newPassword: String,
228245
recaptchaToken: String,
229246
ownershipResponse: String? = null
@@ -241,7 +258,8 @@ class Vaults(val context: Context) {
241258
Base64.DEFAULT))
242259
setClientDeviceIdPubKey(Base64.encodeToString(deviceIdPubKey,
243260
Base64.DEFAULT))
244-
setRecaptchaToken(recaptchaToken)
261+
setCaptchaToken(recaptchaToken)
262+
setEmailAddress(email)
245263

246264
ownershipResponse?.let {
247265
setOwnershipProofResponse(ownershipResponse)
@@ -254,8 +272,10 @@ class Vaults(val context: Context) {
254272
response.longLivedToken,
255273
response.serverDeviceIdPubKey,
256274
response.serverPublishPubKey,
257-
phoneNumber,
258-
deviceIdPubKey, publishPubKey)
275+
email.ifEmpty { phoneNumber },
276+
deviceIdPubKey, publishPubKey,
277+
email.isNotEmpty(),
278+
)
259279
}
260280
return response
261281
}
@@ -366,6 +386,10 @@ class Vaults(val context: Context) {
366386
PUBLISHER_ATTRIBUTE_FILES, Context.MODE_PRIVATE)
367387
sharedPreferences.edit { clear() }
368388

389+
context.getSharedPreferences(Settings.FILENAME, Context.MODE_PRIVATE).apply {
390+
edit { putBoolean(Settings.SETTINGS_IS_EMAIL_LOGIN, false ).apply() }
391+
}
392+
369393
KeystoreHelpers.removeFromKeystore(context, DEVICE_ID_KEYSTORE_ALIAS)
370394
KeystoreHelpers.removeFromKeystore(context, DEVICE_ID_SECRET_KEY_KEYSTORE_ALIAS)
371395
KeystoreHelpers.removeFromKeystore(context, DEVICE_ID_PUB_KEY)

0 commit comments

Comments
 (0)