That fuck shit the fascists are using
at master 117 lines 4.5 kB view raw
1package org.tm.archive.database 2 3import android.content.Context 4import androidx.core.content.contentValuesOf 5import org.signal.core.util.Base64 6import org.signal.core.util.SqlUtil 7import org.signal.core.util.deleteAll 8import org.signal.core.util.logging.Log 9import org.signal.core.util.requireInt 10import org.signal.core.util.requireLong 11import org.signal.core.util.requireNonNullString 12import org.signal.libsignal.protocol.InvalidKeyException 13import org.signal.libsignal.protocol.ecc.Curve 14import org.signal.libsignal.protocol.ecc.ECKeyPair 15import org.signal.libsignal.protocol.state.SignedPreKeyRecord 16import org.whispersystems.signalservice.api.push.ServiceId 17import java.io.IOException 18import java.util.LinkedList 19 20class SignedPreKeyTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTable(context, databaseHelper) { 21 companion object { 22 private val TAG = Log.tag(SignedPreKeyTable::class.java) 23 24 const val TABLE_NAME = "signed_prekeys" 25 const val ID = "_id" 26 const val ACCOUNT_ID = "account_id" 27 const val KEY_ID = "key_id" 28 const val PUBLIC_KEY = "public_key" 29 const val PRIVATE_KEY = "private_key" 30 const val SIGNATURE = "signature" 31 const val TIMESTAMP = "timestamp" 32 33 const val CREATE_TABLE = """ 34 CREATE TABLE $TABLE_NAME ( 35 $ID INTEGER PRIMARY KEY, 36 $ACCOUNT_ID TEXT NOT NULL, 37 $KEY_ID INTEGER NOT NULL, 38 $PUBLIC_KEY TEXT NOT NULL, 39 $PRIVATE_KEY TEXT NOT NULL, 40 $SIGNATURE TEXT NOT NULL, 41 $TIMESTAMP INTEGER DEFAULT 0, 42 UNIQUE($ACCOUNT_ID, $KEY_ID) 43 ) 44 """ 45 46 const val PNI_ACCOUNT_ID = "PNI" 47 } 48 49 fun get(serviceId: ServiceId, keyId: Int): SignedPreKeyRecord? { 50 readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId.toAccountId(), keyId), null, null, null).use { cursor -> 51 if (cursor.moveToFirst()) { 52 try { 53 val publicKey = Curve.decodePoint(Base64.decode(cursor.requireNonNullString(PUBLIC_KEY)), 0) 54 val privateKey = Curve.decodePrivatePoint(Base64.decode(cursor.requireNonNullString(PRIVATE_KEY))) 55 val signature = Base64.decode(cursor.requireNonNullString(SIGNATURE)) 56 val timestamp = cursor.requireLong(TIMESTAMP) 57 return SignedPreKeyRecord(keyId, timestamp, ECKeyPair(publicKey, privateKey), signature) 58 } catch (e: InvalidKeyException) { 59 Log.w(TAG, e) 60 } catch (e: IOException) { 61 Log.w(TAG, e) 62 } 63 } 64 } 65 return null 66 } 67 68 fun getAll(serviceId: ServiceId): List<SignedPreKeyRecord> { 69 val results: MutableList<SignedPreKeyRecord> = LinkedList() 70 71 readableDatabase.query(TABLE_NAME, null, "$ACCOUNT_ID = ?", SqlUtil.buildArgs(serviceId.toAccountId()), null, null, null).use { cursor -> 72 while (cursor.moveToNext()) { 73 try { 74 val keyId = cursor.requireInt(KEY_ID) 75 val publicKey = Curve.decodePoint(Base64.decode(cursor.requireNonNullString(PUBLIC_KEY)), 0) 76 val privateKey = Curve.decodePrivatePoint(Base64.decode(cursor.requireNonNullString(PRIVATE_KEY))) 77 val signature = Base64.decode(cursor.requireNonNullString(SIGNATURE)) 78 val timestamp = cursor.requireLong(TIMESTAMP) 79 results.add(SignedPreKeyRecord(keyId, timestamp, ECKeyPair(publicKey, privateKey), signature)) 80 } catch (e: InvalidKeyException) { 81 Log.w(TAG, e) 82 } catch (e: IOException) { 83 Log.w(TAG, e) 84 } 85 } 86 } 87 88 return results 89 } 90 91 fun insert(serviceId: ServiceId, keyId: Int, record: SignedPreKeyRecord) { 92 val contentValues = contentValuesOf( 93 ACCOUNT_ID to serviceId.toAccountId(), 94 KEY_ID to keyId, 95 PUBLIC_KEY to Base64.encodeWithPadding(record.keyPair.publicKey.serialize()), 96 PRIVATE_KEY to Base64.encodeWithPadding(record.keyPair.privateKey.serialize()), 97 SIGNATURE to Base64.encodeWithPadding(record.signature), 98 TIMESTAMP to record.timestamp 99 ) 100 writableDatabase.replace(TABLE_NAME, null, contentValues) 101 } 102 103 fun delete(serviceId: ServiceId, keyId: Int) { 104 writableDatabase.delete(TABLE_NAME, "$ACCOUNT_ID = ? AND $KEY_ID = ?", SqlUtil.buildArgs(serviceId.toAccountId(), keyId)) 105 } 106 107 fun debugDeleteAll() { 108 writableDatabase.deleteAll(OneTimePreKeyTable.TABLE_NAME) 109 } 110 111 private fun ServiceId.toAccountId(): String { 112 return when (this) { 113 is ServiceId.ACI -> this.toString() 114 is ServiceId.PNI -> PNI_ACCOUNT_ID 115 } 116 } 117}