-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
created content provider and a reset permissions button
- v3.2.5
- v3.2.4
- v3.2.3
- v3.2.2
- v3.2.1
- v3.2.0
- v3.1.9
- v3.1.8
- v3.1.7
- v3.1.6
- v3.1.5
- v3.1.4
- v3.1.3
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.7
- v3.0.6
- v3.0.5
- v3.0.4
- v3.0.3
- v3.0.2
- v3.0.1
- v3.0.0
- v3.0.0-pre9
- v3.0.0-pre8
- v3.0.0-pre7
- v3.0.0-pre6
- v3.0.0-pre5
- v3.0.0-pre4
- v3.0.0-pre3
- v3.0.0-pre2
- v3.0.0-pre1
- v2.0.8
- v2.0.7
- v2.0.6
- v2.0.5
- v2.0.4
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.3.7
- v.1.3.6
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.3.0-pre4
- v1.3.0-pre3
- v1.3.0-pre2
- v1.3.0-pre1
- v1.2.0
- v1.1.2
- v1.1.1
- v1.1.0
- v1.1.0-pre1
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.7-pre2
- v1.0.7-pre1
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-pre12
- v1.0.0-pre11
- v1.0.0-pre10
- v1.0.0-pre9
- v1.0.0-pre8
- v1.0.0-pre7
- v1.0.0-pre6
- v1.0.0-pre5
- v1.0.0-pre4
- v1.0.0-pre3
- v1.0.0-pre2
- v1.0.0-pre
- v0.8.2
- v0.8.1
- v0.8.0
- v0.7.6
- v0.7.5
- v0.7.4
- v0.7.3
- v0.7.2
- v0.7.1
- v0.7.0
- v0.6.6
- v0.6.5
- v0.6.4
- v0.6.3
- v0.6.1
- v0.6.0
- v0.5.3
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.7
- v0.4.6
- v0.4.5
- v0.4.4
- v0.4.3
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.0
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
1 parent
7b98fd8
commit 88d6242
Showing
5 changed files
with
338 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
307 changes: 307 additions & 0 deletions
307
app/src/main/java/com/greenart7c3/nostrsigner/SignerProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,307 @@ | ||
package com.greenart7c3.nostrsigner | ||
|
||
import android.content.ContentProvider | ||
import android.content.ContentValues | ||
import android.database.Cursor | ||
import android.database.MatrixCursor | ||
import android.net.Uri | ||
import android.util.Log | ||
import com.greenart7c3.nostrsigner.service.toNpub | ||
import com.greenart7c3.nostrsigner.ui.encryptPrivateZapMessage | ||
import com.vitorpamplona.quartz.crypto.CryptoUtils | ||
import com.vitorpamplona.quartz.crypto.CryptoUtils.pubkeyCreate | ||
import com.vitorpamplona.quartz.crypto.Nip44Version | ||
import com.vitorpamplona.quartz.crypto.decodeNIP44 | ||
import com.vitorpamplona.quartz.crypto.encodeNIP44 | ||
import com.vitorpamplona.quartz.encoders.hexToByteArray | ||
import com.vitorpamplona.quartz.encoders.toHexKey | ||
import com.vitorpamplona.quartz.events.Event | ||
import com.vitorpamplona.quartz.events.LnZapPrivateEvent | ||
import com.vitorpamplona.quartz.events.LnZapRequestEvent | ||
import fr.acinq.secp256k1.Hex | ||
|
||
class SignerProvider : ContentProvider() { | ||
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int { | ||
return 0 | ||
} | ||
|
||
override fun getType(uri: Uri): String? { | ||
return null | ||
} | ||
|
||
override fun insert(uri: Uri, values: ContentValues?): Uri? { | ||
return null | ||
} | ||
|
||
override fun onCreate(): Boolean { | ||
return true | ||
} | ||
|
||
override fun query( | ||
uri: Uri, | ||
projection: Array<String>?, | ||
selection: String?, | ||
selectionArgs: Array<String>?, | ||
sortOrder: String? | ||
): Cursor? { | ||
return when (uri.toString()) { | ||
"content://com.greenart7c3.nostrsigner.SIGN_EVENT" -> { | ||
val packageName = callingPackage ?: return null | ||
val json = projection?.first() ?: return null | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val event = Event.fromJson(json) | ||
val key = "$packageName-SIGN_EVENT-${event.kind}" | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
if (event is LnZapRequestEvent) { | ||
val isPrivateZap = event.tags.any { tag -> tag.any { t -> t == "anon" } } | ||
val originalNoteId = event.zappedPost()[0] | ||
val pubkey = event.zappedAuthor()[0] | ||
var privkey = account.keyPair.privKey | ||
if (isPrivateZap) { | ||
val encryptionPrivateKey = LnZapRequestEvent.createEncryptionPrivateKey( | ||
privkey.toHexKey(), | ||
originalNoteId, | ||
event.createdAt | ||
) | ||
val noteJson = (LnZapPrivateEvent.create(privkey, listOf(event.tags[0], event.tags[1]), event.content)).toJson() | ||
val encryptedContent = encryptPrivateZapMessage( | ||
noteJson, | ||
encryptionPrivateKey, | ||
pubkey.hexToByteArray() | ||
) | ||
var tags = event.tags.filter { !it.contains("anon") } | ||
tags = tags + listOf(listOf("anon", encryptedContent)) | ||
privkey = encryptionPrivateKey // sign event with generated privkey | ||
val pubKey = pubkeyCreate( | ||
encryptionPrivateKey | ||
).toHexKey() // updated event with according pubkey | ||
|
||
val id = Event.generateId( | ||
pubKey, | ||
event.createdAt, | ||
LnZapRequestEvent.kind, | ||
tags, | ||
"" | ||
) | ||
val sig = com.vitorpamplona.quartz.crypto.CryptoUtils.sign(id, privkey) | ||
val signedEvent = LnZapRequestEvent( | ||
id.toHexKey(), | ||
pubKey, | ||
event.createdAt, | ||
tags, | ||
"", | ||
sig.toHexKey() | ||
) | ||
val cursor = MatrixCursor(arrayOf("signature", "event")) | ||
cursor.addRow(arrayOf(sig, signedEvent.toJson())) | ||
return cursor | ||
} | ||
} | ||
|
||
val id = event.id.hexToByteArray() | ||
val sig = CryptoUtils.sign(id, account.keyPair.privKey).toHexKey() | ||
val signedEvent = Event( | ||
event.id, | ||
event.pubKey, | ||
event.createdAt, | ||
event.kind, | ||
event.tags, | ||
event.content, | ||
sig | ||
) | ||
val cursor = MatrixCursor(arrayOf("signature", "event")) | ||
cursor.addRow(arrayOf(sig, signedEvent.toJson())) | ||
return cursor | ||
} | ||
"content://com.greenart7c3.nostrsigner.NIP04_DECRYPT" -> { | ||
val packageName = callingPackage ?: return null | ||
val encryptedContent = projection?.first() ?: return null | ||
val key = "$packageName-NIP04_DECRYPT" | ||
val pubkey = projection[1] | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
val decrypted = try { | ||
CryptoUtils.decryptNIP04( | ||
encryptedContent, | ||
account.keyPair.privKey, | ||
Hex.decode(pubkey) | ||
) | ||
} catch (e: Exception) { | ||
"Could not decrypt the message" | ||
} | ||
val cursor = MatrixCursor(arrayOf("signature")) | ||
cursor.addRow(arrayOf<Any>(decrypted)) | ||
return cursor | ||
} | ||
"content://com.greenart7c3.nostrsigner.NIP44_DECRYPT" -> { | ||
val packageName = callingPackage ?: return null | ||
val encryptedContent = projection?.first() ?: return null | ||
val key = "$packageName-NIP44_DECRYPT" | ||
val pubkey = projection[1] | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
val decrypted = try { | ||
val toDecrypt = decodeNIP44(encryptedContent) ?: return null | ||
when (toDecrypt.v) { | ||
Nip44Version.NIP04.versionCode -> com.vitorpamplona.quartz.crypto.CryptoUtils.decryptNIP04( | ||
toDecrypt, | ||
account.keyPair.privKey, | ||
pubkey.hexToByteArray() | ||
) | ||
Nip44Version.NIP44.versionCode -> com.vitorpamplona.quartz.crypto.CryptoUtils.decryptNIP44( | ||
toDecrypt, | ||
account.keyPair.privKey, | ||
pubkey.hexToByteArray() | ||
) | ||
else -> null | ||
} ?: "Could not decrypt the message" | ||
} catch (e: Exception) { | ||
"Could not decrypt the message" | ||
} | ||
val cursor = MatrixCursor(arrayOf("signature")) | ||
cursor.addRow(arrayOf<Any>(decrypted)) | ||
return cursor | ||
} | ||
"content://com.greenart7c3.nostrsigner.NIP04_ENCRYPT" -> { | ||
val packageName = callingPackage ?: return null | ||
val decryptedContent = projection?.first() ?: return null | ||
val key = "$packageName-NIP04_ENCRYPT" | ||
val pubkey = projection[1] | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
val encrypted = CryptoUtils.encryptNIP04( | ||
decryptedContent, | ||
account.keyPair.privKey, | ||
Hex.decode(pubkey) | ||
) | ||
|
||
val cursor = MatrixCursor(arrayOf("signature")) | ||
cursor.addRow(arrayOf<Any>(encrypted)) | ||
return cursor | ||
} | ||
"content://com.greenart7c3.nostrsigner.GET_PUBLIC_KEY" -> { | ||
val packageName = callingPackage ?: return null | ||
val key = "$packageName-GET_PUBLIC_KEY" | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
val cursor = MatrixCursor(arrayOf("signature")) | ||
cursor.addRow(arrayOf<Any>(account.keyPair.pubKey.toNpub())) | ||
return cursor | ||
} | ||
"content://com.greenart7c3.nostrsigner.NIP44_ENCRYPT" -> { | ||
val packageName = callingPackage ?: return null | ||
val decryptedContent = projection?.first() ?: return null | ||
val key = "$packageName-NIP44_ENCRYPT" | ||
val pubkey = projection[1] | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
val sharedSecret = CryptoUtils.getSharedSecretNIP44( | ||
account.keyPair.privKey, | ||
pubkey.hexToByteArray() | ||
) | ||
|
||
val encrypted = encodeNIP44( | ||
CryptoUtils.encryptNIP44( | ||
decryptedContent, | ||
sharedSecret | ||
) | ||
) | ||
|
||
val cursor = MatrixCursor(arrayOf("signature")) | ||
cursor.addRow(arrayOf<Any>(encrypted)) | ||
return cursor | ||
} | ||
"content://com.greenart7c3.nostrsigner.DECRYPT_ZAP_EVENT" -> { | ||
val packageName = callingPackage ?: return null | ||
val encryptedContent = projection?.first() ?: return null | ||
val key = "$packageName-DECRYPT_ZAP_EVENT" | ||
val account = LocalPreferences.loadFromEncryptedStorage() ?: return null | ||
val isRemembered = account.savedApps[key] ?: false | ||
if (!isRemembered) return null | ||
|
||
val event = Event.fromJson(encryptedContent) as LnZapRequestEvent | ||
val loggedInPrivateKey = account.keyPair.privKey | ||
|
||
val decrypted = try { | ||
if (event.isPrivateZap()) { | ||
val recipientPK = event.zappedAuthor().firstOrNull() | ||
val recipientPost = event.zappedPost().firstOrNull() | ||
if (recipientPK == account.keyPair.pubKey.toHexKey()) { | ||
// if the receiver is logged in, these are the params. | ||
val privateKeyToUse = loggedInPrivateKey | ||
val pubkeyToUse = event.pubKey | ||
|
||
event.getPrivateZapEvent(privateKeyToUse, pubkeyToUse)?.toJson() ?: "" | ||
} else { | ||
// if the sender is logged in, these are the params | ||
val altPubkeyToUse = recipientPK | ||
val altPrivateKeyToUse = if (recipientPost != null) { | ||
LnZapRequestEvent.createEncryptionPrivateKey( | ||
loggedInPrivateKey.toHexKey(), | ||
recipientPost, | ||
event.createdAt | ||
) | ||
} else if (recipientPK != null) { | ||
LnZapRequestEvent.createEncryptionPrivateKey( | ||
loggedInPrivateKey.toHexKey(), | ||
recipientPK, | ||
event.createdAt | ||
) | ||
} else { | ||
null | ||
} | ||
|
||
try { | ||
if (altPrivateKeyToUse != null && altPubkeyToUse != null) { | ||
val altPubKeyFromPrivate = pubkeyCreate(altPrivateKeyToUse).toHexKey() | ||
|
||
if (altPubKeyFromPrivate == event.pubKey) { | ||
val result = event.getPrivateZapEvent(altPrivateKeyToUse, altPubkeyToUse) | ||
|
||
result?.toJson() ?: "" | ||
} else { | ||
null | ||
} | ||
} else { | ||
null | ||
} | ||
} catch (e: Exception) { | ||
Log.e("Account", "Failed to create pubkey for ZapRequest ${event.id}", e) | ||
null | ||
} | ||
} | ||
} else { | ||
null | ||
} | ||
} catch (e: Exception) { | ||
"Could not decrypt the message" | ||
} ?: "Could not decrypt the message" | ||
val cursor = MatrixCursor(arrayOf("signature")) | ||
cursor.addRow(arrayOf<Any>(decrypted)) | ||
return cursor | ||
} | ||
else -> null | ||
} | ||
} | ||
|
||
override fun update( | ||
uri: Uri, | ||
values: ContentValues?, | ||
selection: String?, | ||
selectionArgs: Array<String>? | ||
): Int { | ||
return 0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters