]> nmode's Git Repositories - signal-cli/commitdiff
Store serviceId in protocol stores as TEXT
authorAsamK <asamk@gmx.de>
Sat, 23 Sep 2023 09:51:50 +0000 (11:51 +0200)
committerAsamK <asamk@gmx.de>
Sat, 23 Sep 2023 09:51:50 +0000 (11:51 +0200)
ServiceIds are no longer just UUIDs, they can now have prefixes like "PNI:"

17 files changed:
lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java
lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java
lib/src/main/java/org/asamk/signal/manager/storage/Utils.java
lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityInfo.java
lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java
lib/src/main/java/org/asamk/signal/manager/storage/identities/LegacyIdentityKeyStore.java
lib/src/main/java/org/asamk/signal/manager/storage/identities/SignalIdentityKeyStore.java
lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonIdentityKeyStore.java
lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonSessionStore.java
lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java
lib/src/main/java/org/asamk/signal/manager/storage/sendLog/MessageSendLogStore.java
lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/LegacySenderKeyRecordStore.java
lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/LegacySenderKeySharedStore.java
lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeyRecordStore.java
lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeySharedStore.java
lib/src/main/java/org/asamk/signal/manager/storage/sessions/LegacySessionStore.java
lib/src/main/java/org/asamk/signal/manager/storage/sessions/SessionStore.java

index f40e23ab54fbf42d62439fc192d21ae2d49554f7..ee202d3928fe4ce25c096ec1ead78efdd76f392b 100644 (file)
@@ -2,6 +2,7 @@ package org.asamk.signal.manager.storage;
 
 import com.zaxxer.hikari.HikariDataSource;
 
 
 import com.zaxxer.hikari.HikariDataSource;
 
+import org.asamk.signal.manager.api.Pair;
 import org.asamk.signal.manager.storage.groups.GroupStore;
 import org.asamk.signal.manager.storage.identities.IdentityKeyStore;
 import org.asamk.signal.manager.storage.prekeys.KyberPreKeyStore;
 import org.asamk.signal.manager.storage.groups.GroupStore;
 import org.asamk.signal.manager.storage.identities.IdentityKeyStore;
 import org.asamk.signal.manager.storage.prekeys.KyberPreKeyStore;
@@ -15,16 +16,21 @@ import org.asamk.signal.manager.storage.sessions.SessionStore;
 import org.asamk.signal.manager.storage.stickers.StickerStore;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.asamk.signal.manager.storage.stickers.StickerStore;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.whispersystems.signalservice.api.push.ServiceId;
 import org.whispersystems.signalservice.api.push.ServiceId.ACI;
 import org.whispersystems.signalservice.api.push.ServiceId.ACI;
+import org.whispersystems.signalservice.api.util.UuidUtil;
 
 import java.io.File;
 import java.sql.Connection;
 import java.sql.SQLException;
 
 import java.io.File;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Optional;
+import java.util.UUID;
 
 public class AccountDatabase extends Database {
 
     private final static Logger logger = LoggerFactory.getLogger(AccountDatabase.class);
 
 public class AccountDatabase extends Database {
 
     private final static Logger logger = LoggerFactory.getLogger(AccountDatabase.class);
-    private static final long DATABASE_VERSION = 14;
+    private static final long DATABASE_VERSION = 15;
 
     private AccountDatabase(final HikariDataSource dataSource) {
         super(logger, DATABASE_VERSION, dataSource);
 
     private AccountDatabase(final HikariDataSource dataSource) {
         super(logger, DATABASE_VERSION, dataSource);
@@ -346,7 +352,146 @@ public class AccountDatabase extends Database {
                                             """);
                 }
             }
                                             """);
                 }
             }
+        }
+        if (oldVersion < 15) {
+            logger.debug("Updating database: Store serviceId as TEXT");
+            try (final var statement = connection.createStatement()) {
+                statement.executeUpdate("""
+                                        CREATE TABLE tmp_mapping_table (
+                                          uuid BLOB NOT NULL,
+                                          address TEXT NOT NULL
+                                        ) STRICT;
+                                        """);
+
+                final var sql = (
+                        """
+                        SELECT r.uuid, r.pni
+                        FROM recipient r
+                        """
+                );
+                final var uuidAddressMapping = new HashMap<UUID, ServiceId>();
+                try (final var preparedStatement = connection.prepareStatement(sql)) {
+                    try (var result = Utils.executeQueryForStream(preparedStatement, (resultSet) -> {
+                        final var pni = Optional.ofNullable(resultSet.getBytes("pni"))
+                                .map(UuidUtil::parseOrNull)
+                                .map(ServiceId.PNI::from);
+                        final var serviceIdUuid = Optional.ofNullable(resultSet.getBytes("uuid"))
+                                .map(UuidUtil::parseOrNull);
+                        final var serviceId = serviceIdUuid.isPresent() && pni.isPresent() && serviceIdUuid.get()
+                                .equals(pni.get().getRawUuid())
+                                ? pni.<ServiceId>map(p -> p)
+                                : serviceIdUuid.<ServiceId>map(ACI::from);
+
+                        return new Pair<>(serviceId, pni);
+                    })) {
+                        result.forEach(p -> {
+                            final var serviceId = p.first();
+                            final var pni = p.second();
+                            if (serviceId.isPresent()) {
+                                uuidAddressMapping.put(serviceId.get().getRawUuid(), serviceId.get());
+                            }
+                            if (pni.isPresent()) {
+                                uuidAddressMapping.put(pni.get().getRawUuid(), pni.get());
+                            }
+                        });
+                    }
+                }
+
+                final var insertSql = """
+                                      INSERT INTO tmp_mapping_table (uuid, address)
+                                      VALUES (?,?)
+                                      """;
+                try (final var insertStatement = connection.prepareStatement(insertSql)) {
+                    for (final var entry : uuidAddressMapping.entrySet()) {
+                        final var uuid = entry.getKey();
+                        final var serviceId = entry.getValue();
+                        insertStatement.setBytes(1, UuidUtil.toByteArray(uuid));
+                        insertStatement.setString(2, serviceId.toString());
+                        insertStatement.execute();
+                    }
+                }
+
+                statement.executeUpdate("""
+                                        CREATE TABLE identity2 (
+                                          _id INTEGER PRIMARY KEY,
+                                          address TEXT UNIQUE NOT NULL,
+                                          identity_key BLOB NOT NULL,
+                                          added_timestamp INTEGER NOT NULL,
+                                          trust_level INTEGER NOT NULL
+                                        ) STRICT;
+                                        INSERT INTO identity2 (_id, address, identity_key, added_timestamp, trust_level)
+                                          SELECT i._id, (SELECT t.address FROM tmp_mapping_table t WHERE t.uuid = i.uuid) address, i.identity_key, i.added_timestamp, i.trust_level
+                                          FROM identity i
+                                          WHERE address IS NOT NULL;
+                                        DROP TABLE identity;
+                                        ALTER TABLE identity2 RENAME TO identity;
 
 
+                                        CREATE TABLE message_send_log2 (
+                                          _id INTEGER PRIMARY KEY,
+                                          content_id INTEGER NOT NULL REFERENCES message_send_log_content (_id) ON DELETE CASCADE,
+                                          address TEXT NOT NULL,
+                                          device_id INTEGER NOT NULL
+                                        ) STRICT;
+                                        INSERT INTO message_send_log2 (_id, content_id, address, device_id)
+                                          SELECT m._id, m.content_id, (SELECT t.address FROM tmp_mapping_table t WHERE t.uuid = m.uuid) address, m.device_id
+                                          FROM message_send_log m
+                                          WHERE address IS NOT NULL;
+                                        DROP INDEX msl_recipient_index;
+                                        DROP INDEX msl_content_index;
+                                        DROP TABLE message_send_log;
+                                        ALTER TABLE message_send_log2 RENAME TO message_send_log;
+                                        CREATE INDEX msl_recipient_index ON message_send_log (address, device_id, content_id);
+                                        CREATE INDEX msl_content_index ON message_send_log (content_id);
+
+                                        CREATE TABLE sender_key2 (
+                                          _id INTEGER PRIMARY KEY,
+                                          address TEXT NOT NULL,
+                                          device_id INTEGER NOT NULL,
+                                          distribution_id BLOB NOT NULL,
+                                          record BLOB NOT NULL,
+                                          created_timestamp INTEGER NOT NULL,
+                                          UNIQUE(address, device_id, distribution_id)
+                                        ) STRICT;
+                                        INSERT INTO sender_key2 (_id, address, device_id, distribution_id, record, created_timestamp)
+                                          SELECT s._id, (SELECT t.address FROM tmp_mapping_table t WHERE t.uuid = s.uuid) address, s.device_id, s.distribution_id, s.record, s.created_timestamp
+                                          FROM sender_key s
+                                          WHERE address IS NOT NULL;
+                                        DROP TABLE sender_key;
+                                        ALTER TABLE sender_key2 RENAME TO sender_key;
+
+                                        CREATE TABLE sender_key_shared2 (
+                                          _id INTEGER PRIMARY KEY,
+                                          address TEXT NOT NULL,
+                                          device_id INTEGER NOT NULL,
+                                          distribution_id BLOB NOT NULL,
+                                          timestamp INTEGER NOT NULL,
+                                          UNIQUE(address, device_id, distribution_id)
+                                        ) STRICT;
+                                        INSERT INTO sender_key_shared2 (_id, address, device_id, distribution_id, timestamp)
+                                          SELECT s._id, (SELECT t.address FROM tmp_mapping_table t WHERE t.uuid = s.uuid) address, s.device_id, s.distribution_id, s.timestamp
+                                          FROM sender_key_shared s
+                                          WHERE address IS NOT NULL;
+                                        DROP TABLE sender_key_shared;
+                                        ALTER TABLE sender_key_shared2 RENAME TO sender_key_shared;
+
+                                        CREATE TABLE session2 (
+                                          _id INTEGER PRIMARY KEY,
+                                          account_id_type INTEGER NOT NULL,
+                                          address TEXT NOT NULL,
+                                          device_id INTEGER NOT NULL,
+                                          record BLOB NOT NULL,
+                                          UNIQUE(account_id_type, address, device_id)
+                                        ) STRICT;
+                                        INSERT INTO session2 (_id, account_id_type, address, device_id, record)
+                                          SELECT s._id, s.account_id_type, (SELECT t.address FROM tmp_mapping_table t WHERE t.uuid = s.uuid) address, s.device_id, s.record
+                                          FROM session s
+                                          WHERE address IS NOT NULL;
+                                        DROP TABLE session;
+                                        ALTER TABLE session2 RENAME TO session;
+
+                                        DROP TABLE tmp_mapping_table;
+                                        """);
+            }
         }
     }
 }
         }
     }
 }
index 6ae2aaa477d624acf8d194c47b92a8b955ec5101..1619eabd4150a6f4f7378dddc39783fafc66857b 100644 (file)
@@ -1841,8 +1841,7 @@ public class SignalAccount implements Closeable {
 
         public SignalIdentityKeyStore getIdentityKeyStore() {
             return getOrCreate(() -> identityKeyStore,
 
         public SignalIdentityKeyStore getIdentityKeyStore() {
             return getOrCreate(() -> identityKeyStore,
-                    () -> identityKeyStore = new SignalIdentityKeyStore(getRecipientResolver(),
-                            () -> identityKeyPair,
+                    () -> identityKeyStore = new SignalIdentityKeyStore(() -> identityKeyPair,
                             localRegistrationId,
                             SignalAccount.this.getIdentityKeyStore()));
         }
                             localRegistrationId,
                             SignalAccount.this.getIdentityKeyStore()));
         }
index de98d7e5ca28fc2e45753e1c7e0d9457dfd0251f..fa2e8916f1dec58a68eca1c5bf51254b8571a7bb 100644 (file)
@@ -56,7 +56,7 @@ public class Utils {
         return node;
     }
 
         return node;
     }
 
-    public static RecipientAddress getRecipientAddressFromIdentifier(final String identifier) {
+    public static RecipientAddress getRecipientAddressFromLegacyIdentifier(final String identifier) {
         if (UuidUtil.isUuid(identifier)) {
             return new RecipientAddress(ServiceId.parseOrThrow(identifier));
         } else {
         if (UuidUtil.isUuid(identifier)) {
             return new RecipientAddress(ServiceId.parseOrThrow(identifier));
         } else {
index 585ba945151556c4eb1309c96c197d6854d5c3fa..d00d455c8aec3acaac69ba8fb7cd27a0c1511c92 100644 (file)
@@ -6,26 +6,26 @@ import org.whispersystems.signalservice.api.push.ServiceId;
 
 public class IdentityInfo {
 
 
 public class IdentityInfo {
 
-    private final String name;
+    private final String address;
     private final IdentityKey identityKey;
     private final TrustLevel trustLevel;
     private final long addedTimestamp;
 
     IdentityInfo(
     private final IdentityKey identityKey;
     private final TrustLevel trustLevel;
     private final long addedTimestamp;
 
     IdentityInfo(
-            final String name, IdentityKey identityKey, TrustLevel trustLevel, long addedTimestamp
+            final String address, IdentityKey identityKey, TrustLevel trustLevel, long addedTimestamp
     ) {
     ) {
-        this.name = name;
+        this.address = address;
         this.identityKey = identityKey;
         this.trustLevel = trustLevel;
         this.addedTimestamp = addedTimestamp;
     }
 
     public ServiceId getServiceId() {
         this.identityKey = identityKey;
         this.trustLevel = trustLevel;
         this.addedTimestamp = addedTimestamp;
     }
 
     public ServiceId getServiceId() {
-        return ServiceId.parseOrThrow(name);
+        return ServiceId.parseOrThrow(address);
     }
 
     }
 
-    public String getName() {
-        return name;
+    public String getAddress() {
+        return address;
     }
 
     public IdentityKey getIdentityKey() {
     }
 
     public IdentityKey getIdentityKey() {
index 2f8b4dac7a813d6de4a35b9fe9df9b5a59907b1a..3195df171a8ca6c45e338dba223cacccf8d90051 100644 (file)
@@ -37,7 +37,7 @@ public class IdentityKeyStore {
             statement.executeUpdate("""
                                     CREATE TABLE identity (
                                       _id INTEGER PRIMARY KEY,
             statement.executeUpdate("""
                                     CREATE TABLE identity (
                                       _id INTEGER PRIMARY KEY,
-                                      uuid BLOB UNIQUE NOT NULL,
+                                      address TEXT UNIQUE NOT NULL,
                                       identity_key BLOB NOT NULL,
                                       added_timestamp INTEGER NOT NULL,
                                       trust_level INTEGER NOT NULL
                                       identity_key BLOB NOT NULL,
                                       added_timestamp INTEGER NOT NULL,
                                       trust_level INTEGER NOT NULL
@@ -56,18 +56,22 @@ public class IdentityKeyStore {
     }
 
     public boolean saveIdentity(final ServiceId serviceId, final IdentityKey identityKey) {
     }
 
     public boolean saveIdentity(final ServiceId serviceId, final IdentityKey identityKey) {
+        return saveIdentity(serviceId.toString(), identityKey);
+    }
+
+    boolean saveIdentity(final String address, final IdentityKey identityKey) {
         if (isRetryingDecryption) {
             return false;
         }
         try (final var connection = database.getConnection()) {
         if (isRetryingDecryption) {
             return false;
         }
         try (final var connection = database.getConnection()) {
-            final var identityInfo = loadIdentity(connection, serviceId);
+            final var identityInfo = loadIdentity(connection, address);
             if (identityInfo != null && identityInfo.getIdentityKey().equals(identityKey)) {
                 // Identity already exists, not updating the trust level
             if (identityInfo != null && identityInfo.getIdentityKey().equals(identityKey)) {
                 // Identity already exists, not updating the trust level
-                logger.trace("Not storing new identity for recipient {}, identity already stored", serviceId);
+                logger.trace("Not storing new identity for recipient {}, identity already stored", address);
                 return false;
             }
 
                 return false;
             }
 
-            saveNewIdentity(connection, serviceId, identityKey, identityInfo == null);
+            saveNewIdentity(connection, address, identityKey, identityInfo == null);
             return true;
         } catch (SQLException e) {
             throw new RuntimeException("Failed update identity store", e);
             return true;
         } catch (SQLException e) {
             throw new RuntimeException("Failed update identity store", e);
@@ -80,7 +84,8 @@ public class IdentityKeyStore {
 
     public boolean setIdentityTrustLevel(ServiceId serviceId, IdentityKey identityKey, TrustLevel trustLevel) {
         try (final var connection = database.getConnection()) {
 
     public boolean setIdentityTrustLevel(ServiceId serviceId, IdentityKey identityKey, TrustLevel trustLevel) {
         try (final var connection = database.getConnection()) {
-            final var identityInfo = loadIdentity(connection, serviceId);
+            final var address = serviceId.toString();
+            final var identityInfo = loadIdentity(connection, address);
             if (identityInfo == null) {
                 logger.debug("Not updating trust level for recipient {}, identity not found", serviceId);
                 return false;
             if (identityInfo == null) {
                 logger.debug("Not updating trust level for recipient {}, identity not found", serviceId);
                 return false;
@@ -95,7 +100,7 @@ public class IdentityKeyStore {
             }
 
             logger.debug("Updating trust level for recipient {} with trust {}", serviceId, trustLevel);
             }
 
             logger.debug("Updating trust level for recipient {} with trust {}", serviceId, trustLevel);
-            final var newIdentityInfo = new IdentityInfo(serviceId,
+            final var newIdentityInfo = new IdentityInfo(address,
                     identityKey,
                     trustLevel,
                     identityInfo.getDateAddedTimestamp());
                     identityKey,
                     trustLevel,
                     identityInfo.getDateAddedTimestamp());
@@ -107,31 +112,35 @@ public class IdentityKeyStore {
     }
 
     public boolean isTrustedIdentity(ServiceId serviceId, IdentityKey identityKey, Direction direction) {
     }
 
     public boolean isTrustedIdentity(ServiceId serviceId, IdentityKey identityKey, Direction direction) {
+        return isTrustedIdentity(serviceId.toString(), identityKey, direction);
+    }
+
+    public boolean isTrustedIdentity(String address, IdentityKey identityKey, Direction direction) {
         if (trustNewIdentity == TrustNewIdentity.ALWAYS) {
             return true;
         }
 
         try (final var connection = database.getConnection()) {
             // TODO implement possibility for different handling of incoming/outgoing trust decisions
         if (trustNewIdentity == TrustNewIdentity.ALWAYS) {
             return true;
         }
 
         try (final var connection = database.getConnection()) {
             // TODO implement possibility for different handling of incoming/outgoing trust decisions
-            var identityInfo = loadIdentity(connection, serviceId);
+            var identityInfo = loadIdentity(connection, address);
             if (identityInfo == null) {
             if (identityInfo == null) {
-                logger.debug("Initial identity found for {}, saving.", serviceId);
-                saveNewIdentity(connection, serviceId, identityKey, true);
-                identityInfo = loadIdentity(connection, serviceId);
+                logger.debug("Initial identity found for {}, saving.", address);
+                saveNewIdentity(connection, address, identityKey, true);
+                identityInfo = loadIdentity(connection, address);
             } else if (!identityInfo.getIdentityKey().equals(identityKey)) {
                 // Identity found, but different
                 if (direction == Direction.SENDING) {
             } else if (!identityInfo.getIdentityKey().equals(identityKey)) {
                 // Identity found, but different
                 if (direction == Direction.SENDING) {
-                    logger.debug("Changed identity found for {}, saving.", serviceId);
-                    saveNewIdentity(connection, serviceId, identityKey, false);
-                    identityInfo = loadIdentity(connection, serviceId);
+                    logger.debug("Changed identity found for {}, saving.", address);
+                    saveNewIdentity(connection, address, identityKey, false);
+                    identityInfo = loadIdentity(connection, address);
                 } else {
                 } else {
-                    logger.trace("Trusting identity for {} for {}: {}", serviceId, direction, false);
+                    logger.trace("Trusting identity for {} for {}: {}", address, direction, false);
                     return false;
                 }
             }
 
             final var isTrusted = identityInfo != null && identityInfo.isTrusted();
                     return false;
                 }
             }
 
             final var isTrusted = identityInfo != null && identityInfo.isTrusted();
-            logger.trace("Trusting identity for {} for {}: {}", serviceId, direction, isTrusted);
+            logger.trace("Trusting identity for {} for {}: {}", address, direction, isTrusted);
             return isTrusted;
         } catch (SQLException e) {
             throw new RuntimeException("Failed read from identity store", e);
             return isTrusted;
         } catch (SQLException e) {
             throw new RuntimeException("Failed read from identity store", e);
@@ -139,8 +148,12 @@ public class IdentityKeyStore {
     }
 
     public IdentityInfo getIdentityInfo(ServiceId serviceId) {
     }
 
     public IdentityInfo getIdentityInfo(ServiceId serviceId) {
+        return getIdentityInfo(serviceId.toString());
+    }
+
+    public IdentityInfo getIdentityInfo(String address) {
         try (final var connection = database.getConnection()) {
         try (final var connection = database.getConnection()) {
-            return loadIdentity(connection, serviceId);
+            return loadIdentity(connection, address);
         } catch (SQLException e) {
             throw new RuntimeException("Failed read from identity store", e);
         }
         } catch (SQLException e) {
             throw new RuntimeException("Failed read from identity store", e);
         }
@@ -150,7 +163,7 @@ public class IdentityKeyStore {
         try (final var connection = database.getConnection()) {
             final var sql = (
                     """
         try (final var connection = database.getConnection()) {
             final var sql = (
                     """
-                    SELECT i.uuid, i.identity_key, i.added_timestamp, i.trust_level
+                    SELECT i.address, i.identity_key, i.added_timestamp, i.trust_level
                     FROM %s AS i
                     """
             ).formatted(TABLE_IDENTITY);
                     FROM %s AS i
                     """
             ).formatted(TABLE_IDENTITY);
@@ -166,7 +179,7 @@ public class IdentityKeyStore {
 
     public void deleteIdentity(final ServiceId serviceId) {
         try (final var connection = database.getConnection()) {
 
     public void deleteIdentity(final ServiceId serviceId) {
         try (final var connection = database.getConnection()) {
-            deleteIdentity(connection, serviceId);
+            deleteIdentity(connection, serviceId.toString());
         } catch (SQLException e) {
             throw new RuntimeException("Failed update identity store", e);
         }
         } catch (SQLException e) {
             throw new RuntimeException("Failed update identity store", e);
         }
@@ -188,34 +201,37 @@ public class IdentityKeyStore {
     }
 
     private IdentityInfo loadIdentity(
     }
 
     private IdentityInfo loadIdentity(
-            final Connection connection, final ServiceId serviceId
+            final Connection connection, final String address
     ) throws SQLException {
         final var sql = (
                 """
     ) throws SQLException {
         final var sql = (
                 """
-                SELECT i.uuid, i.identity_key, i.added_timestamp, i.trust_level
+                SELECT i.address, i.identity_key, i.added_timestamp, i.trust_level
                 FROM %s AS i
                 FROM %s AS i
-                WHERE i.uuid = ?
+                WHERE i.address = ?
                 """
         ).formatted(TABLE_IDENTITY);
         try (final var statement = connection.prepareStatement(sql)) {
                 """
         ).formatted(TABLE_IDENTITY);
         try (final var statement = connection.prepareStatement(sql)) {
-            statement.setBytes(1, serviceId.toByteArray());
+            statement.setString(1, address);
             return Utils.executeQueryForOptional(statement, this::getIdentityInfoFromResultSet).orElse(null);
         }
     }
 
     private void saveNewIdentity(
             final Connection connection,
             return Utils.executeQueryForOptional(statement, this::getIdentityInfoFromResultSet).orElse(null);
         }
     }
 
     private void saveNewIdentity(
             final Connection connection,
-            final ServiceId serviceId,
+            final String address,
             final IdentityKey identityKey,
             final boolean firstIdentity
     ) throws SQLException {
         final var trustLevel = trustNewIdentity == TrustNewIdentity.ALWAYS || (
                 trustNewIdentity == TrustNewIdentity.ON_FIRST_USE && firstIdentity
         ) ? TrustLevel.TRUSTED_UNVERIFIED : TrustLevel.UNTRUSTED;
             final IdentityKey identityKey,
             final boolean firstIdentity
     ) throws SQLException {
         final var trustLevel = trustNewIdentity == TrustNewIdentity.ALWAYS || (
                 trustNewIdentity == TrustNewIdentity.ON_FIRST_USE && firstIdentity
         ) ? TrustLevel.TRUSTED_UNVERIFIED : TrustLevel.UNTRUSTED;
-        logger.debug("Storing new identity for recipient {} with trust {}", serviceId, trustLevel);
-        final var newIdentityInfo = new IdentityInfo(serviceId, identityKey, trustLevel, System.currentTimeMillis());
+        logger.debug("Storing new identity for recipient {} with trust {}", address, trustLevel);
+        final var newIdentityInfo = new IdentityInfo(address, identityKey, trustLevel, System.currentTimeMillis());
         storeIdentity(connection, newIdentityInfo);
         storeIdentity(connection, newIdentityInfo);
-        identityChanges.onNext(serviceId);
+        final var serviceId = ServiceId.parseOrNull(address);
+        if (serviceId != null) {
+            identityChanges.onNext(serviceId);
+        }
     }
 
     private void storeIdentity(final Connection connection, final IdentityInfo identityInfo) throws SQLException {
     }
 
     private void storeIdentity(final Connection connection, final IdentityInfo identityInfo) throws SQLException {
@@ -225,12 +241,12 @@ public class IdentityKeyStore {
                 identityInfo.getDateAddedTimestamp());
         final var sql = (
                 """
                 identityInfo.getDateAddedTimestamp());
         final var sql = (
                 """
-                INSERT OR REPLACE INTO %s (uuid, identity_key, added_timestamp, trust_level)
+                INSERT OR REPLACE INTO %s (address, identity_key, added_timestamp, trust_level)
                 VALUES (?, ?, ?, ?)
                 """
         ).formatted(TABLE_IDENTITY);
         try (final var statement = connection.prepareStatement(sql)) {
                 VALUES (?, ?, ?, ?)
                 """
         ).formatted(TABLE_IDENTITY);
         try (final var statement = connection.prepareStatement(sql)) {
-            statement.setBytes(1, identityInfo.getServiceId().toByteArray());
+            statement.setString(1, identityInfo.getAddress());
             statement.setBytes(2, identityInfo.getIdentityKey().serialize());
             statement.setLong(3, identityInfo.getDateAddedTimestamp());
             statement.setInt(4, identityInfo.getTrustLevel().ordinal());
             statement.setBytes(2, identityInfo.getIdentityKey().serialize());
             statement.setLong(3, identityInfo.getDateAddedTimestamp());
             statement.setInt(4, identityInfo.getTrustLevel().ordinal());
@@ -238,27 +254,27 @@ public class IdentityKeyStore {
         }
     }
 
         }
     }
 
-    private void deleteIdentity(final Connection connection, final ServiceId serviceId) throws SQLException {
+    private void deleteIdentity(final Connection connection, final String address) throws SQLException {
         final var sql = (
                 """
                 DELETE FROM %s AS i
         final var sql = (
                 """
                 DELETE FROM %s AS i
-                WHERE i.uuid = ?
+                WHERE i.address = ?
                 """
         ).formatted(TABLE_IDENTITY);
         try (final var statement = connection.prepareStatement(sql)) {
                 """
         ).formatted(TABLE_IDENTITY);
         try (final var statement = connection.prepareStatement(sql)) {
-            statement.setBytes(1, serviceId.toByteArray());
+            statement.setString(1, address);
             statement.executeUpdate();
         }
     }
 
     private IdentityInfo getIdentityInfoFromResultSet(ResultSet resultSet) throws SQLException {
         try {
             statement.executeUpdate();
         }
     }
 
     private IdentityInfo getIdentityInfoFromResultSet(ResultSet resultSet) throws SQLException {
         try {
-            final var serviceId = ServiceId.parseOrThrow(resultSet.getBytes("uuid"));
+            final var address = resultSet.getString("address");
             final var id = new IdentityKey(resultSet.getBytes("identity_key"));
             final var trustLevel = TrustLevel.fromInt(resultSet.getInt("trust_level"));
             final var added = resultSet.getLong("added_timestamp");
 
             final var id = new IdentityKey(resultSet.getBytes("identity_key"));
             final var trustLevel = TrustLevel.fromInt(resultSet.getInt("trust_level"));
             final var added = resultSet.getLong("added_timestamp");
 
-            return new IdentityInfo(serviceId, id, trustLevel, added);
+            return new IdentityInfo(address, id, trustLevel, added);
         } catch (InvalidKeyException e) {
             logger.warn("Failed to load identity key, resetting: {}", e.getMessage());
             return null;
         } catch (InvalidKeyException e) {
             logger.warn("Failed to load identity key, resetting: {}", e.getMessage());
             return null;
index 88e23e7560b9301032a3645f6b3578db49a682e2..27cb6f84005de6d94281a480eb94234458c03596 100644 (file)
@@ -84,7 +84,7 @@ public class LegacyIdentityKeyStore {
             var added = storage.addedTimestamp();
 
             final var serviceId = address.serviceId().get();
             var added = storage.addedTimestamp();
 
             final var serviceId = address.serviceId().get();
-            return new IdentityInfo(serviceId, id, trustLevel, added);
+            return new IdentityInfo(serviceId.toString(), id, trustLevel, added);
         } catch (IOException | InvalidKeyException e) {
             logger.warn("Failed to load identity key: {}", e.getMessage());
             return null;
         } catch (IOException | InvalidKeyException e) {
             logger.warn("Failed to load identity key: {}", e.getMessage());
             return null;
index 66dfec4e24f800bd2e9fe9bfe3910edbfe572084..5a1a676eeb31bd43cc142e4dbad7273fb4c47d44 100644 (file)
@@ -1,10 +1,8 @@
 package org.asamk.signal.manager.storage.identities;
 
 package org.asamk.signal.manager.storage.identities;
 
-import org.asamk.signal.manager.storage.recipients.RecipientResolver;
 import org.signal.libsignal.protocol.IdentityKey;
 import org.signal.libsignal.protocol.IdentityKeyPair;
 import org.signal.libsignal.protocol.SignalProtocolAddress;
 import org.signal.libsignal.protocol.IdentityKey;
 import org.signal.libsignal.protocol.IdentityKeyPair;
 import org.signal.libsignal.protocol.SignalProtocolAddress;
-import org.whispersystems.signalservice.api.push.ServiceId;
 
 import java.util.function.Supplier;
 
 
 import java.util.function.Supplier;
 
@@ -15,7 +13,6 @@ public class SignalIdentityKeyStore implements org.signal.libsignal.protocol.sta
     private final IdentityKeyStore identityKeyStore;
 
     public SignalIdentityKeyStore(
     private final IdentityKeyStore identityKeyStore;
 
     public SignalIdentityKeyStore(
-            final RecipientResolver resolver,
             final Supplier<IdentityKeyPair> identityKeyPairSupplier,
             final int localRegistrationId,
             final IdentityKeyStore identityKeyStore
             final Supplier<IdentityKeyPair> identityKeyPairSupplier,
             final int localRegistrationId,
             final IdentityKeyStore identityKeyStore
@@ -37,22 +34,17 @@ public class SignalIdentityKeyStore implements org.signal.libsignal.protocol.sta
 
     @Override
     public boolean saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
 
     @Override
     public boolean saveIdentity(SignalProtocolAddress address, IdentityKey identityKey) {
-        final var serviceId = ServiceId.parseOrThrow(address.getName());
-
-        return identityKeyStore.saveIdentity(serviceId, identityKey);
+        return identityKeyStore.saveIdentity(address.getName(), identityKey);
     }
 
     @Override
     public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, Direction direction) {
     }
 
     @Override
     public boolean isTrustedIdentity(SignalProtocolAddress address, IdentityKey identityKey, Direction direction) {
-        final var serviceId = ServiceId.parseOrThrow(address.getName());
-
-        return identityKeyStore.isTrustedIdentity(serviceId, identityKey, direction);
+        return identityKeyStore.isTrustedIdentity(address.getName(), identityKey, direction);
     }
 
     @Override
     public IdentityKey getIdentity(SignalProtocolAddress address) {
     }
 
     @Override
     public IdentityKey getIdentity(SignalProtocolAddress address) {
-        final var serviceId = ServiceId.parseOrThrow(address.getName());
-        final var identityInfo = identityKeyStore.getIdentityInfo(serviceId);
+        final var identityInfo = identityKeyStore.getIdentityInfo(address.getName());
         return identityInfo == null ? null : identityInfo.getIdentityKey();
     }
 }
         return identityInfo == null ? null : identityInfo.getIdentityKey();
     }
 }
index 56986333a36ab769f8eaf14e3587035656f72e42..1e95eaff99620a057c13c67c8919585ec3aff0b3 100644 (file)
@@ -100,7 +100,7 @@ public class LegacyJsonIdentityKeyStore {
                             ? UuidUtil.parseOrNull(trustedKey.get("uuid").asText())
                             : null;
                     final var address = uuid == null
                             ? UuidUtil.parseOrNull(trustedKey.get("uuid").asText())
                             : null;
                     final var address = uuid == null
-                            ? Utils.getRecipientAddressFromIdentifier(trustedKeyName)
+                            ? Utils.getRecipientAddressFromLegacyIdentifier(trustedKeyName)
                             : new RecipientAddress(ACI.from(uuid), trustedKeyName);
                     try {
                         var id = new IdentityKey(Base64.getDecoder().decode(trustedKey.get("identityKey").asText()), 0);
                             : new RecipientAddress(ACI.from(uuid), trustedKeyName);
                     try {
                         var id = new IdentityKey(Base64.getDecoder().decode(trustedKey.get("identityKey").asText()), 0);
index 73a85f76a5c21ea9f6497dd12ba1046b439f4b77..ee675d780c1f9d4a2680c75320a3a33e4f026e1a 100644 (file)
@@ -47,7 +47,7 @@ public class LegacyJsonSessionStore {
 
                     var uuid = session.hasNonNull("uuid") ? UuidUtil.parseOrNull(session.get("uuid").asText()) : null;
                     final var address = uuid == null
 
                     var uuid = session.hasNonNull("uuid") ? UuidUtil.parseOrNull(session.get("uuid").asText()) : null;
                     final var address = uuid == null
-                            ? Utils.getRecipientAddressFromIdentifier(sessionName)
+                            ? Utils.getRecipientAddressFromLegacyIdentifier(sessionName)
                             : new RecipientAddress(ACI.from(uuid), sessionName);
                     final var deviceId = session.get("deviceId").asInt();
                     final var record = Base64.getDecoder().decode(session.get("record").asText());
                             : new RecipientAddress(ACI.from(uuid), sessionName);
                     final var deviceId = session.get("deviceId").asInt();
                     final var record = Base64.getDecoder().decode(session.get("record").asText());
index f19111b06f272945bc87d36f15a432f7071b6b63..9ef734c70f8fbeab46d1f452bdad1127b4aa6109 100644 (file)
@@ -151,8 +151,9 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
 
     @Override
     public RecipientId resolveRecipient(final String identifier) {
 
     @Override
     public RecipientId resolveRecipient(final String identifier) {
-        if (UuidUtil.isUuid(identifier)) {
-            return resolveRecipient(ServiceId.parseOrThrow(identifier));
+        final var serviceId = ServiceId.parseOrNull(identifier);
+        if (serviceId != null) {
+            return resolveRecipient(serviceId);
         } else {
             return resolveRecipientByNumber(identifier);
         }
         } else {
             return resolveRecipientByNumber(identifier);
         }
index 88ebe3b2ecff6d399f64c5bcf60b8af64865798d..08b23933703528cac6e834601755724590072c9d 100644 (file)
@@ -67,7 +67,7 @@ public class MessageSendLogStore implements AutoCloseable {
                                     CREATE TABLE message_send_log (
                                       _id INTEGER PRIMARY KEY,
                                       content_id INTEGER NOT NULL REFERENCES message_send_log_content (_id) ON DELETE CASCADE,
                                     CREATE TABLE message_send_log (
                                       _id INTEGER PRIMARY KEY,
                                       content_id INTEGER NOT NULL REFERENCES message_send_log_content (_id) ON DELETE CASCADE,
-                                      uuid BLOB NOT NULL,
+                                      address TEXT NOT NULL,
                                       device_id INTEGER NOT NULL
                                     ) STRICT;
                                     CREATE TABLE message_send_log_content (
                                       device_id INTEGER NOT NULL
                                     ) STRICT;
                                     CREATE TABLE message_send_log_content (
@@ -79,7 +79,7 @@ public class MessageSendLogStore implements AutoCloseable {
                                       urgent INTEGER NOT NULL
                                     ) STRICT;
                                     CREATE INDEX mslc_timestamp_index ON message_send_log_content (timestamp);
                                       urgent INTEGER NOT NULL
                                     ) STRICT;
                                     CREATE INDEX mslc_timestamp_index ON message_send_log_content (timestamp);
-                                    CREATE INDEX msl_recipient_index ON message_send_log (uuid, device_id, content_id);
+                                    CREATE INDEX msl_recipient_index ON message_send_log (address, device_id, content_id);
                                     CREATE INDEX msl_content_index ON message_send_log (content_id);
                                     """);
         }
                                     CREATE INDEX msl_content_index ON message_send_log (content_id);
                                     """);
         }
@@ -92,13 +92,13 @@ public class MessageSendLogStore implements AutoCloseable {
                         SELECT group_id, content, content_hint, urgent
                         FROM %s l
                              INNER JOIN %s lc ON l.content_id = lc._id
                         SELECT group_id, content, content_hint, urgent
                         FROM %s l
                              INNER JOIN %s lc ON l.content_id = lc._id
-                        WHERE l.uuid = ? AND l.device_id = ? AND lc.timestamp = ?
+                        WHERE l.address = ? AND l.device_id = ? AND lc.timestamp = ?
                         """.formatted(TABLE_MESSAGE_SEND_LOG, TABLE_MESSAGE_SEND_LOG_CONTENT);
         try (final var connection = database.getConnection()) {
             deleteOutdatedEntries(connection);
 
             try (final var statement = connection.prepareStatement(sql)) {
                         """.formatted(TABLE_MESSAGE_SEND_LOG, TABLE_MESSAGE_SEND_LOG_CONTENT);
         try (final var connection = database.getConnection()) {
             deleteOutdatedEntries(connection);
 
             try (final var statement = connection.prepareStatement(sql)) {
-                statement.setBytes(1, serviceId.toByteArray());
+                statement.setString(1, serviceId.toString());
                 statement.setInt(2, deviceId);
                 statement.setLong(3, timestamp);
                 try (var result = Utils.executeQueryForStream(statement, this::getMessageSendLogEntryFromResultSet)) {
                 statement.setInt(2, deviceId);
                 statement.setLong(3, timestamp);
                 try (var result = Utils.executeQueryForStream(statement, this::getMessageSendLogEntryFromResultSet)) {
@@ -202,13 +202,13 @@ public class MessageSendLogStore implements AutoCloseable {
     public void deleteEntryForRecipientNonGroup(long sentTimestamp, ServiceId serviceId) {
         final var sql = """
                         DELETE FROM %s AS lc
     public void deleteEntryForRecipientNonGroup(long sentTimestamp, ServiceId serviceId) {
         final var sql = """
                         DELETE FROM %s AS lc
-                        WHERE lc.timestamp = ? AND lc.group_id IS NULL AND lc._id IN (SELECT content_id FROM %s l WHERE l.uuid = ?)
+                        WHERE lc.timestamp = ? AND lc.group_id IS NULL AND lc._id IN (SELECT content_id FROM %s l WHERE l.address = ?)
                         """.formatted(TABLE_MESSAGE_SEND_LOG_CONTENT, TABLE_MESSAGE_SEND_LOG);
         try (final var connection = database.getConnection()) {
             connection.setAutoCommit(false);
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setLong(1, sentTimestamp);
                         """.formatted(TABLE_MESSAGE_SEND_LOG_CONTENT, TABLE_MESSAGE_SEND_LOG);
         try (final var connection = database.getConnection()) {
             connection.setAutoCommit(false);
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setLong(1, sentTimestamp);
-                statement.setBytes(2, serviceId.toByteArray());
+                statement.setString(2, serviceId.toString());
                 statement.executeUpdate();
             }
 
                 statement.executeUpdate();
             }
 
@@ -226,14 +226,14 @@ public class MessageSendLogStore implements AutoCloseable {
     public void deleteEntriesForRecipient(List<Long> sentTimestamps, ServiceId serviceId, int deviceId) {
         final var sql = """
                         DELETE FROM %s AS l
     public void deleteEntriesForRecipient(List<Long> sentTimestamps, ServiceId serviceId, int deviceId) {
         final var sql = """
                         DELETE FROM %s AS l
-                        WHERE l.content_id IN (SELECT _id FROM %s lc WHERE lc.timestamp = ?) AND l.uuid = ? AND l.device_id = ?
+                        WHERE l.content_id IN (SELECT _id FROM %s lc WHERE lc.timestamp = ?) AND l.address = ? AND l.device_id = ?
                         """.formatted(TABLE_MESSAGE_SEND_LOG, TABLE_MESSAGE_SEND_LOG_CONTENT);
         try (final var connection = database.getConnection()) {
             connection.setAutoCommit(false);
             try (final var statement = connection.prepareStatement(sql)) {
                 for (final var sentTimestamp : sentTimestamps) {
                     statement.setLong(1, sentTimestamp);
                         """.formatted(TABLE_MESSAGE_SEND_LOG, TABLE_MESSAGE_SEND_LOG_CONTENT);
         try (final var connection = database.getConnection()) {
             connection.setAutoCommit(false);
             try (final var statement = connection.prepareStatement(sql)) {
                 for (final var sentTimestamp : sentTimestamps) {
                     statement.setLong(1, sentTimestamp);
-                    statement.setBytes(2, serviceId.toByteArray());
+                    statement.setString(2, serviceId.toString());
                     statement.setInt(3, deviceId);
                     statement.executeUpdate();
                 }
                     statement.setInt(3, deviceId);
                     statement.executeUpdate();
                 }
@@ -342,13 +342,13 @@ public class MessageSendLogStore implements AutoCloseable {
             final long contentId, final List<RecipientDevices> recipientDevices, final Connection connection
     ) throws SQLException {
         final var sql = """
             final long contentId, final List<RecipientDevices> recipientDevices, final Connection connection
     ) throws SQLException {
         final var sql = """
-                        INSERT INTO %s (uuid, device_id, content_id)
+                        INSERT INTO %s (address, device_id, content_id)
                         VALUES (?,?,?)
                         """.formatted(TABLE_MESSAGE_SEND_LOG);
         try (final var statement = connection.prepareStatement(sql)) {
             for (final var recipientDevice : recipientDevices) {
                 for (final var deviceId : recipientDevice.deviceIds()) {
                         VALUES (?,?,?)
                         """.formatted(TABLE_MESSAGE_SEND_LOG);
         try (final var statement = connection.prepareStatement(sql)) {
             for (final var recipientDevice : recipientDevices) {
                 for (final var deviceId : recipientDevice.deviceIds()) {
-                    statement.setBytes(1, recipientDevice.serviceId().toByteArray());
+                    statement.setString(1, recipientDevice.serviceId().toString());
                     statement.setInt(2, deviceId);
                     statement.setLong(3, contentId);
                     statement.executeUpdate();
                     statement.setInt(2, deviceId);
                     statement.setLong(3, contentId);
                     statement.executeUpdate();
index d17941567a93a1e0358cc32a23a0f4b46e088171..64928624ef969552e1f02c70eb990614e932b71d 100644 (file)
@@ -41,7 +41,9 @@ public class LegacySenderKeyRecordStore {
             if (record == null || serviceId.isEmpty()) {
                 return null;
             }
             if (record == null || serviceId.isEmpty()) {
                 return null;
             }
-            return new Pair<>(new SenderKeyRecordStore.Key(serviceId.get(), key.deviceId, key.distributionId), record);
+            return new Pair<>(new SenderKeyRecordStore.Key(serviceId.get().toString(),
+                    key.deviceId,
+                    key.distributionId), record);
         }).filter(Objects::nonNull).toList();
 
         senderKeyStore.addLegacySenderKeys(senderKeys);
         }).filter(Objects::nonNull).toList();
 
         senderKeyStore.addLegacySenderKeys(senderKeys);
index b46f850607499f69eb4d663bc18d5312a6d786e6..bbd05dea9d6f9a7b129720a0f850b983311cfbbc 100644 (file)
@@ -40,7 +40,7 @@ public class LegacySenderKeySharedStore {
                 if (serviceId.isEmpty()) {
                     continue;
                 }
                 if (serviceId.isEmpty()) {
                     continue;
                 }
-                final var entry = new SenderKeySharedEntry(serviceId.get(), senderKey.deviceId);
+                final var entry = new SenderKeySharedEntry(serviceId.get().toString(), senderKey.deviceId);
                 final var distributionId = DistributionId.from(senderKey.distributionId);
                 var entries = sharedSenderKeys.get(distributionId);
                 if (entries == null) {
                 final var distributionId = DistributionId.from(senderKey.distributionId);
                 var entries = sharedSenderKeys.get(distributionId);
                 if (entries == null) {
index 5e42a924ff36eb8fb5bf206438fe5092350bb624..e321e9eafaefe103ccd7be66216545c6c9a9cce9 100644 (file)
@@ -31,12 +31,12 @@ public class SenderKeyRecordStore implements SenderKeyStore {
             statement.executeUpdate("""
                                     CREATE TABLE sender_key (
                                       _id INTEGER PRIMARY KEY,
             statement.executeUpdate("""
                                     CREATE TABLE sender_key (
                                       _id INTEGER PRIMARY KEY,
-                                      uuid BLOB NOT NULL,
+                                      address TEXT NOT NULL,
                                       device_id INTEGER NOT NULL,
                                       distribution_id BLOB NOT NULL,
                                       record BLOB NOT NULL,
                                       created_timestamp INTEGER NOT NULL,
                                       device_id INTEGER NOT NULL,
                                       distribution_id BLOB NOT NULL,
                                       record BLOB NOT NULL,
                                       created_timestamp INTEGER NOT NULL,
-                                      UNIQUE(uuid, device_id, distribution_id)
+                                      UNIQUE(address, device_id, distribution_id)
                                     ) STRICT;
                                     """);
         }
                                     ) STRICT;
                                     """);
         }
@@ -75,12 +75,12 @@ public class SenderKeyRecordStore implements SenderKeyStore {
                 """
                 SELECT s.created_timestamp
                 FROM %s AS s
                 """
                 SELECT s.created_timestamp
                 FROM %s AS s
-                WHERE s.uuid = ? AND s.device_id = ? AND s.distribution_id = ?
+                WHERE s.address = ? AND s.device_id = ? AND s.distribution_id = ?
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var connection = database.getConnection()) {
             try (final var statement = connection.prepareStatement(sql)) {
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var connection = database.getConnection()) {
             try (final var statement = connection.prepareStatement(sql)) {
-                statement.setBytes(1, selfServiceId.toByteArray());
+                statement.setString(1, selfServiceId.toString());
                 statement.setInt(2, selfDeviceId);
                 statement.setBytes(3, UuidUtil.toByteArray(distributionId));
                 return Utils.executeQueryForOptional(statement, res -> res.getLong("created_timestamp")).orElse(-1L);
                 statement.setInt(2, selfDeviceId);
                 statement.setBytes(3, UuidUtil.toByteArray(distributionId));
                 return Utils.executeQueryForOptional(statement, res -> res.getLong("created_timestamp")).orElse(-1L);
@@ -94,12 +94,12 @@ public class SenderKeyRecordStore implements SenderKeyStore {
         final var sql = (
                 """
                 DELETE FROM %s AS s
         final var sql = (
                 """
                 DELETE FROM %s AS s
-                WHERE s.uuid = ? AND s.distribution_id = ?
+                WHERE s.address = ? AND s.distribution_id = ?
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var connection = database.getConnection()) {
             try (final var statement = connection.prepareStatement(sql)) {
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var connection = database.getConnection()) {
             try (final var statement = connection.prepareStatement(sql)) {
-                statement.setBytes(1, serviceId.toByteArray());
+                statement.setString(1, serviceId.toString());
                 statement.setBytes(2, UuidUtil.toByteArray(distributionId));
                 statement.executeUpdate();
             }
                 statement.setBytes(2, UuidUtil.toByteArray(distributionId));
                 statement.executeUpdate();
             }
@@ -145,8 +145,7 @@ public class SenderKeyRecordStore implements SenderKeyStore {
     }
 
     private Key getKey(final SignalProtocolAddress address, final UUID distributionId) {
     }
 
     private Key getKey(final SignalProtocolAddress address, final UUID distributionId) {
-        final var serviceId = ServiceId.parseOrThrow(address.getName());
-        return new Key(serviceId, address.getDeviceId(), distributionId);
+        return new Key(address.getName(), address.getDeviceId(), distributionId);
     }
 
     private SenderKeyRecord loadSenderKey(final Connection connection, final Key key) throws SQLException {
     }
 
     private SenderKeyRecord loadSenderKey(final Connection connection, final Key key) throws SQLException {
@@ -154,11 +153,11 @@ public class SenderKeyRecordStore implements SenderKeyStore {
                 """
                 SELECT s.record
                 FROM %s AS s
                 """
                 SELECT s.record
                 FROM %s AS s
-                WHERE s.uuid = ? AND s.device_id = ? AND s.distribution_id = ?
+                WHERE s.address = ? AND s.device_id = ? AND s.distribution_id = ?
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sql)) {
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sql)) {
-            statement.setBytes(1, key.serviceId().toByteArray());
+            statement.setString(1, key.address());
             statement.setInt(2, key.deviceId());
             statement.setBytes(3, UuidUtil.toByteArray(key.distributionId()));
             return Utils.executeQueryForOptional(statement, this::getSenderKeyRecordFromResultSet).orElse(null);
             statement.setInt(2, key.deviceId());
             statement.setBytes(3, UuidUtil.toByteArray(key.distributionId()));
             return Utils.executeQueryForOptional(statement, this::getSenderKeyRecordFromResultSet).orElse(null);
@@ -171,11 +170,11 @@ public class SenderKeyRecordStore implements SenderKeyStore {
         final var sqlUpdate = """
                               UPDATE %s
                               SET record = ?
         final var sqlUpdate = """
                               UPDATE %s
                               SET record = ?
-                              WHERE uuid = ? AND device_id = ? and distribution_id = ?
+                              WHERE address = ? AND device_id = ? and distribution_id = ?
                               """.formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sqlUpdate)) {
             statement.setBytes(1, senderKeyRecord.serialize());
                               """.formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sqlUpdate)) {
             statement.setBytes(1, senderKeyRecord.serialize());
-            statement.setBytes(2, key.serviceId().toByteArray());
+            statement.setString(2, key.address());
             statement.setLong(3, key.deviceId());
             statement.setBytes(4, UuidUtil.toByteArray(key.distributionId()));
             final var rows = statement.executeUpdate();
             statement.setLong(3, key.deviceId());
             statement.setBytes(4, UuidUtil.toByteArray(key.distributionId()));
             final var rows = statement.executeUpdate();
@@ -187,12 +186,12 @@ public class SenderKeyRecordStore implements SenderKeyStore {
         // Record doesn't exist yet, creating a new one
         final var sqlInsert = (
                 """
         // Record doesn't exist yet, creating a new one
         final var sqlInsert = (
                 """
-                INSERT OR REPLACE INTO %s (uuid, device_id, distribution_id, record, created_timestamp)
+                INSERT OR REPLACE INTO %s (address, device_id, distribution_id, record, created_timestamp)
                 VALUES (?, ?, ?, ?, ?)
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sqlInsert)) {
                 VALUES (?, ?, ?, ?, ?)
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sqlInsert)) {
-            statement.setBytes(1, key.serviceId().toByteArray());
+            statement.setString(1, key.address());
             statement.setInt(2, key.deviceId());
             statement.setBytes(3, UuidUtil.toByteArray(key.distributionId()));
             statement.setBytes(4, senderKeyRecord.serialize());
             statement.setInt(2, key.deviceId());
             statement.setBytes(3, UuidUtil.toByteArray(key.distributionId()));
             statement.setBytes(4, senderKeyRecord.serialize());
@@ -205,11 +204,11 @@ public class SenderKeyRecordStore implements SenderKeyStore {
         final var sql = (
                 """
                 DELETE FROM %s AS s
         final var sql = (
                 """
                 DELETE FROM %s AS s
-                WHERE s.uuid = ?
+                WHERE s.address = ?
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sql)) {
                 """
         ).formatted(TABLE_SENDER_KEY);
         try (final var statement = connection.prepareStatement(sql)) {
-            statement.setBytes(1, serviceId.toByteArray());
+            statement.setString(1, serviceId.toString());
             statement.executeUpdate();
         }
     }
             statement.executeUpdate();
         }
     }
@@ -225,5 +224,5 @@ public class SenderKeyRecordStore implements SenderKeyStore {
         }
     }
 
         }
     }
 
-    record Key(ServiceId serviceId, int deviceId, UUID distributionId) {}
+    record Key(String address, int deviceId, UUID distributionId) {}
 }
 }
index 112c358c8943d14788761bb8fc865281c6863369..0b17d479147d360d488d65ad0206475525cff550 100644 (file)
@@ -30,11 +30,11 @@ public class SenderKeySharedStore {
             statement.executeUpdate("""
                                     CREATE TABLE sender_key_shared (
                                       _id INTEGER PRIMARY KEY,
             statement.executeUpdate("""
                                     CREATE TABLE sender_key_shared (
                                       _id INTEGER PRIMARY KEY,
-                                      uuid BLOB NOT NULL,
+                                      address TEXT NOT NULL,
                                       device_id INTEGER NOT NULL,
                                       distribution_id BLOB NOT NULL,
                                       timestamp INTEGER NOT NULL,
                                       device_id INTEGER NOT NULL,
                                       distribution_id BLOB NOT NULL,
                                       timestamp INTEGER NOT NULL,
-                                      UNIQUE(uuid, device_id, distribution_id)
+                                      UNIQUE(address, device_id, distribution_id)
                                     ) STRICT;
                                     """);
         }
                                     ) STRICT;
                                     """);
         }
@@ -48,7 +48,7 @@ public class SenderKeySharedStore {
         try (final var connection = database.getConnection()) {
             final var sql = (
                     """
         try (final var connection = database.getConnection()) {
             final var sql = (
                     """
-                    SELECT s.uuid, s.device_id
+                    SELECT s.address, s.device_id
                     FROM %s AS s
                     WHERE s.distribution_id = ?
                     """
                     FROM %s AS s
                     WHERE s.distribution_id = ?
                     """
@@ -56,7 +56,7 @@ public class SenderKeySharedStore {
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setBytes(1, UuidUtil.toByteArray(distributionId.asUuid()));
                 return Utils.executeQueryForStream(statement, this::getSenderKeySharedEntryFromResultSet)
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setBytes(1, UuidUtil.toByteArray(distributionId.asUuid()));
                 return Utils.executeQueryForStream(statement, this::getSenderKeySharedEntryFromResultSet)
-                        .map(k -> k.serviceId.toProtocolAddress(k.deviceId()))
+                        .map(k -> new SignalProtocolAddress(k.address, k.deviceId()))
                         .collect(Collectors.toSet());
             }
         } catch (SQLException e) {
                         .collect(Collectors.toSet());
             }
         } catch (SQLException e) {
@@ -68,7 +68,7 @@ public class SenderKeySharedStore {
             final DistributionId distributionId, final Collection<SignalProtocolAddress> addresses
     ) {
         final var newEntries = addresses.stream()
             final DistributionId distributionId, final Collection<SignalProtocolAddress> addresses
     ) {
         final var newEntries = addresses.stream()
-                .map(a -> new SenderKeySharedEntry(ServiceId.parseOrThrow(a.getName()), a.getDeviceId()))
+                .map(a -> new SenderKeySharedEntry(a.getName(), a.getDeviceId()))
                 .collect(Collectors.toSet());
 
         try (final var connection = database.getConnection()) {
                 .collect(Collectors.toSet());
 
         try (final var connection = database.getConnection()) {
@@ -82,8 +82,7 @@ public class SenderKeySharedStore {
 
     public void clearSenderKeySharedWith(final Collection<SignalProtocolAddress> addresses) {
         final var entriesToDelete = addresses.stream()
 
     public void clearSenderKeySharedWith(final Collection<SignalProtocolAddress> addresses) {
         final var entriesToDelete = addresses.stream()
-                .filter(a -> UuidUtil.isUuid(a.getName()))
-                .map(a -> new SenderKeySharedEntry(ServiceId.parseOrThrow(a.getName()), a.getDeviceId()))
+                .map(a -> new SenderKeySharedEntry(a.getName(), a.getDeviceId()))
                 .collect(Collectors.toSet());
 
         try (final var connection = database.getConnection()) {
                 .collect(Collectors.toSet());
 
         try (final var connection = database.getConnection()) {
@@ -91,12 +90,12 @@ public class SenderKeySharedStore {
             final var sql = (
                     """
                     DELETE FROM %s AS s
             final var sql = (
                     """
                     DELETE FROM %s AS s
-                    WHERE uuid = ? AND device_id = ?
+                    WHERE address = ? AND device_id = ?
                     """
             ).formatted(TABLE_SENDER_KEY_SHARED);
             try (final var statement = connection.prepareStatement(sql)) {
                 for (final var entry : entriesToDelete) {
                     """
             ).formatted(TABLE_SENDER_KEY_SHARED);
             try (final var statement = connection.prepareStatement(sql)) {
                 for (final var entry : entriesToDelete) {
-                    statement.setBytes(1, entry.serviceId().toByteArray());
+                    statement.setString(1, entry.address());
                     statement.setInt(2, entry.deviceId());
                     statement.executeUpdate();
                 }
                     statement.setInt(2, entry.deviceId());
                     statement.executeUpdate();
                 }
@@ -127,11 +126,11 @@ public class SenderKeySharedStore {
             final var sql = (
                     """
                     DELETE FROM %s AS s
             final var sql = (
                     """
                     DELETE FROM %s AS s
-                    WHERE uuid = ?
+                    WHERE address = ?
                     """
             ).formatted(TABLE_SENDER_KEY_SHARED);
             try (final var statement = connection.prepareStatement(sql)) {
                     """
             ).formatted(TABLE_SENDER_KEY_SHARED);
             try (final var statement = connection.prepareStatement(sql)) {
-                statement.setBytes(1, serviceId.toByteArray());
+                statement.setString(1, serviceId.toString());
                 statement.executeUpdate();
             }
         } catch (SQLException e) {
                 statement.executeUpdate();
             }
         } catch (SQLException e) {
@@ -146,11 +145,11 @@ public class SenderKeySharedStore {
             final var sql = (
                     """
                     DELETE FROM %s AS s
             final var sql = (
                     """
                     DELETE FROM %s AS s
-                    WHERE uuid = ? AND device_id = ? AND distribution_id = ?
+                    WHERE address = ? AND device_id = ? AND distribution_id = ?
                     """
             ).formatted(TABLE_SENDER_KEY_SHARED);
             try (final var statement = connection.prepareStatement(sql)) {
                     """
             ).formatted(TABLE_SENDER_KEY_SHARED);
             try (final var statement = connection.prepareStatement(sql)) {
-                statement.setBytes(1, serviceId.toByteArray());
+                statement.setString(1, serviceId.toString());
                 statement.setInt(2, deviceId);
                 statement.setBytes(3, UuidUtil.toByteArray(distributionId.asUuid()));
                 statement.executeUpdate();
                 statement.setInt(2, deviceId);
                 statement.setBytes(3, UuidUtil.toByteArray(distributionId.asUuid()));
                 statement.executeUpdate();
@@ -197,13 +196,13 @@ public class SenderKeySharedStore {
     ) throws SQLException {
         final var sql = (
                 """
     ) throws SQLException {
         final var sql = (
                 """
-                INSERT OR REPLACE INTO %s (uuid, device_id, distribution_id, timestamp)
+                INSERT OR REPLACE INTO %s (address, device_id, distribution_id, timestamp)
                 VALUES (?, ?, ?, ?)
                 """
         ).formatted(TABLE_SENDER_KEY_SHARED);
         try (final var statement = connection.prepareStatement(sql)) {
             for (final var entry : newEntries) {
                 VALUES (?, ?, ?, ?)
                 """
         ).formatted(TABLE_SENDER_KEY_SHARED);
         try (final var statement = connection.prepareStatement(sql)) {
             for (final var entry : newEntries) {
-                statement.setBytes(1, entry.serviceId().toByteArray());
+                statement.setString(1, entry.toString());
                 statement.setInt(2, entry.deviceId());
                 statement.setBytes(3, UuidUtil.toByteArray(distributionId.asUuid()));
                 statement.setLong(4, System.currentTimeMillis());
                 statement.setInt(2, entry.deviceId());
                 statement.setBytes(3, UuidUtil.toByteArray(distributionId.asUuid()));
                 statement.setLong(4, System.currentTimeMillis());
@@ -213,10 +212,10 @@ public class SenderKeySharedStore {
     }
 
     private SenderKeySharedEntry getSenderKeySharedEntryFromResultSet(ResultSet resultSet) throws SQLException {
     }
 
     private SenderKeySharedEntry getSenderKeySharedEntryFromResultSet(ResultSet resultSet) throws SQLException {
-        final var serviceId = ServiceId.parseOrThrow(resultSet.getBytes("uuid"));
+        final var address = resultSet.getString("address");
         final var deviceId = resultSet.getInt("device_id");
         final var deviceId = resultSet.getInt("device_id");
-        return new SenderKeySharedEntry(serviceId, deviceId);
+        return new SenderKeySharedEntry(address, deviceId);
     }
 
     }
 
-    record SenderKeySharedEntry(ServiceId serviceId, int deviceId) {}
+    record SenderKeySharedEntry(String address, int deviceId) {}
 }
 }
index 71cd92310c0801eb5372ff18f91aa245dcf6726a..517271dad41db08bbe5b5966525b0ecdedcdfee2 100644 (file)
@@ -37,7 +37,7 @@ public class LegacySessionStore {
             if (record == null || serviceId.isEmpty()) {
                 return null;
             }
             if (record == null || serviceId.isEmpty()) {
                 return null;
             }
-            return new Pair<>(new SessionStore.Key(serviceId.get(), key.deviceId()), record);
+            return new Pair<>(new SessionStore.Key(serviceId.get().toString(), key.deviceId()), record);
         }).filter(Objects::nonNull).toList();
         sessionStore.addLegacySessions(sessions);
         deleteAllSessions(sessionsPath);
         }).filter(Objects::nonNull).toList();
         sessionStore.addLegacySessions(sessions);
         deleteAllSessions(sessionsPath);
index 3608e0c12ae370364363576a9fe133743802dc2b..ebbd87aa6fd75c1edaf18e9cd6b7d76ad8333959 100644 (file)
@@ -6,15 +6,12 @@ import org.asamk.signal.manager.storage.Utils;
 import org.signal.libsignal.protocol.NoSessionException;
 import org.signal.libsignal.protocol.SignalProtocolAddress;
 import org.signal.libsignal.protocol.ecc.ECPublicKey;
 import org.signal.libsignal.protocol.NoSessionException;
 import org.signal.libsignal.protocol.SignalProtocolAddress;
 import org.signal.libsignal.protocol.ecc.ECPublicKey;
-import org.signal.libsignal.protocol.message.CiphertextMessage;
 import org.signal.libsignal.protocol.state.SessionRecord;
 import org.signal.libsignal.protocol.state.SessionRecord;
-import org.signal.libsignal.protocol.util.Hex;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.SignalServiceSessionStore;
 import org.whispersystems.signalservice.api.push.ServiceId;
 import org.whispersystems.signalservice.api.push.ServiceIdType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.SignalServiceSessionStore;
 import org.whispersystems.signalservice.api.push.ServiceId;
 import org.whispersystems.signalservice.api.push.ServiceIdType;
-import org.whispersystems.signalservice.api.util.UuidUtil;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
@@ -45,10 +42,10 @@ public class SessionStore implements SignalServiceSessionStore {
                                     CREATE TABLE session (
                                       _id INTEGER PRIMARY KEY,
                                       account_id_type INTEGER NOT NULL,
                                     CREATE TABLE session (
                                       _id INTEGER PRIMARY KEY,
                                       account_id_type INTEGER NOT NULL,
-                                      uuid BLOB NOT NULL,
+                                      address TEXT NOT NULL,
                                       device_id INTEGER NOT NULL,
                                       record BLOB NOT NULL,
                                       device_id INTEGER NOT NULL,
                                       record BLOB NOT NULL,
-                                      UNIQUE(account_id_type, uuid, device_id)
+                                      UNIQUE(account_id_type, address, device_id)
                                     ) STRICT;
                                     """);
         }
                                     ) STRICT;
                                     """);
         }
@@ -107,13 +104,13 @@ public class SessionStore implements SignalServiceSessionStore {
                 """
                 SELECT s.device_id
                 FROM %s AS s
                 """
                 SELECT s.device_id
                 FROM %s AS s
-                WHERE s.account_id_type = ? AND s.uuid = ? AND s.device_id != 1
+                WHERE s.account_id_type = ? AND s.address = ? AND s.device_id != 1
                 """
         ).formatted(TABLE_SESSION);
         try (final var connection = database.getConnection()) {
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setInt(1, accountIdType);
                 """
         ).formatted(TABLE_SESSION);
         try (final var connection = database.getConnection()) {
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setInt(1, accountIdType);
-                statement.setBytes(2, serviceId.toByteArray());
+                statement.setString(2, serviceId.toString());
                 return Utils.executeQueryForStream(statement, res -> res.getInt("device_id")).toList();
             }
         } catch (SQLException e) {
                 return Utils.executeQueryForStream(statement, res -> res.getInt("device_id")).toList();
             }
         } catch (SQLException e) {
@@ -122,7 +119,7 @@ public class SessionStore implements SignalServiceSessionStore {
     }
 
     public boolean isCurrentRatchetKey(ServiceId serviceId, int deviceId, ECPublicKey ratchetKey) {
     }
 
     public boolean isCurrentRatchetKey(ServiceId serviceId, int deviceId, ECPublicKey ratchetKey) {
-        final var key = new Key(serviceId, deviceId);
+        final var key = new Key(serviceId.toString(), deviceId);
 
         try (final var connection = database.getConnection()) {
             final var session = loadSession(connection, key);
 
         try (final var connection = database.getConnection()) {
             final var session = loadSession(connection, key);
@@ -177,7 +174,7 @@ public class SessionStore implements SignalServiceSessionStore {
 
     public void deleteAllSessions(ServiceId serviceId) {
         try (final var connection = database.getConnection()) {
 
     public void deleteAllSessions(ServiceId serviceId) {
         try (final var connection = database.getConnection()) {
-            deleteAllSessions(connection, serviceId);
+            deleteAllSessions(connection, serviceId.toString());
         } catch (SQLException e) {
             throw new RuntimeException("Failed update session store", e);
         }
         } catch (SQLException e) {
             throw new RuntimeException("Failed update session store", e);
         }
@@ -185,10 +182,6 @@ public class SessionStore implements SignalServiceSessionStore {
 
     @Override
     public void archiveSession(final SignalProtocolAddress address) {
 
     @Override
     public void archiveSession(final SignalProtocolAddress address) {
-        if (!UuidUtil.isUuid(address.getName())) {
-            return;
-        }
-
         final var key = getKey(address);
 
         try (final var connection = database.getConnection()) {
         final var key = getKey(address);
 
         try (final var connection = database.getConnection()) {
@@ -207,15 +200,13 @@ public class SessionStore implements SignalServiceSessionStore {
     @Override
     public Set<SignalProtocolAddress> getAllAddressesWithActiveSessions(final List<String> addressNames) {
         final var serviceIdsCommaSeparated = addressNames.stream()
     @Override
     public Set<SignalProtocolAddress> getAllAddressesWithActiveSessions(final List<String> addressNames) {
         final var serviceIdsCommaSeparated = addressNames.stream()
-                .map(ServiceId::parseOrThrow)
-                .map(ServiceId::toByteArray)
-                .map(uuid -> "x'" + Hex.toStringCondensed(uuid) + "'")
+                .map(address -> "'" + address.replaceAll("'", "''") + "'")
                 .collect(Collectors.joining(","));
         final var sql = (
                 """
                 .collect(Collectors.joining(","));
         final var sql = (
                 """
-                SELECT s.uuid, s.device_id, s.record
+                SELECT s.address, s.device_id, s.record
                 FROM %s AS s
                 FROM %s AS s
-                WHERE s.account_id_type = ? AND s.uuid IN (%s)
+                WHERE s.account_id_type = ? AND s.address IN (%s)
                 """
         ).formatted(TABLE_SESSION, serviceIdsCommaSeparated);
         try (final var connection = database.getConnection()) {
                 """
         ).formatted(TABLE_SESSION, serviceIdsCommaSeparated);
         try (final var connection = database.getConnection()) {
@@ -225,7 +216,7 @@ public class SessionStore implements SignalServiceSessionStore {
                                 res -> new Pair<>(getKeyFromResultSet(res), getSessionRecordFromResultSet(res)))
                         .filter(pair -> isActive(pair.second()))
                         .map(Pair::first)
                                 res -> new Pair<>(getKeyFromResultSet(res), getSessionRecordFromResultSet(res)))
                         .filter(pair -> isActive(pair.second()))
                         .map(Pair::first)
-                        .map(key -> key.serviceId().toProtocolAddress(key.deviceId()))
+                        .map(key -> new SignalProtocolAddress(key.address(), key.deviceId()))
                         .collect(Collectors.toSet());
             }
         } catch (SQLException e) {
                         .collect(Collectors.toSet());
             }
         } catch (SQLException e) {
@@ -236,7 +227,7 @@ public class SessionStore implements SignalServiceSessionStore {
     public void archiveAllSessions() {
         final var sql = (
                 """
     public void archiveAllSessions() {
         final var sql = (
                 """
-                SELECT s.uuid, s.device_id, s.record
+                SELECT s.address, s.device_id, s.record
                 FROM %s AS s
                 WHERE s.account_id_type = ?
                 """
                 FROM %s AS s
                 WHERE s.account_id_type = ?
                 """
@@ -264,9 +255,9 @@ public class SessionStore implements SignalServiceSessionStore {
     public void archiveSessions(final ServiceId serviceId) {
         final var sql = (
                 """
     public void archiveSessions(final ServiceId serviceId) {
         final var sql = (
                 """
-                SELECT s.uuid, s.device_id, s.record
+                SELECT s.address, s.device_id, s.record
                 FROM %s AS s
                 FROM %s AS s
-                WHERE s.account_id_type = ? AND s.uuid = ?
+                WHERE s.account_id_type = ? AND s.address = ?
                 """
         ).formatted(TABLE_SESSION);
         try (final var connection = database.getConnection()) {
                 """
         ).formatted(TABLE_SESSION);
         try (final var connection = database.getConnection()) {
@@ -274,7 +265,7 @@ public class SessionStore implements SignalServiceSessionStore {
             final List<Pair<Key, SessionRecord>> records;
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setInt(1, accountIdType);
             final List<Pair<Key, SessionRecord>> records;
             try (final var statement = connection.prepareStatement(sql)) {
                 statement.setInt(1, accountIdType);
-                statement.setBytes(2, serviceId.toByteArray());
+                statement.setString(2, serviceId.toString());
                 records = Utils.executeQueryForStream(statement,
                                 res -> new Pair<>(getKeyFromResultSet(res), getSessionRecordFromResultSet(res)))
                         .filter(Objects::nonNull)
                 records = Utils.executeQueryForStream(statement,
                                 res -> new Pair<>(getKeyFromResultSet(res), getSessionRecordFromResultSet(res)))
                         .filter(Objects::nonNull)
@@ -306,8 +297,7 @@ public class SessionStore implements SignalServiceSessionStore {
     }
 
     private Key getKey(final SignalProtocolAddress address) {
     }
 
     private Key getKey(final SignalProtocolAddress address) {
-        final var serviceId = ServiceId.parseOrThrow(address.getName());
-        return new Key(serviceId, address.getDeviceId());
+        return new Key(address.getName(), address.getDeviceId());
     }
 
     private SessionRecord loadSession(Connection connection, final Key key) throws SQLException {
     }
 
     private SessionRecord loadSession(Connection connection, final Key key) throws SQLException {
@@ -321,21 +311,21 @@ public class SessionStore implements SignalServiceSessionStore {
                 """
                 SELECT s.record
                 FROM %s AS s
                 """
                 SELECT s.record
                 FROM %s AS s
-                WHERE s.account_id_type = ? AND s.uuid = ? AND s.device_id = ?
+                WHERE s.account_id_type = ? AND s.address = ? AND s.device_id = ?
                 """
         ).formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
                 """
         ).formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
-            statement.setBytes(2, key.serviceId().toByteArray());
+            statement.setString(2, key.address());
             statement.setInt(3, key.deviceId());
             return Utils.executeQueryForOptional(statement, this::getSessionRecordFromResultSet).orElse(null);
         }
     }
 
     private Key getKeyFromResultSet(ResultSet resultSet) throws SQLException {
             statement.setInt(3, key.deviceId());
             return Utils.executeQueryForOptional(statement, this::getSessionRecordFromResultSet).orElse(null);
         }
     }
 
     private Key getKeyFromResultSet(ResultSet resultSet) throws SQLException {
-        final var serviceId = ServiceId.parseOrThrow(resultSet.getBytes("uuid"));
+        final var address = resultSet.getString("address");
         final var deviceId = resultSet.getInt("device_id");
         final var deviceId = resultSet.getInt("device_id");
-        return new Key(serviceId, deviceId);
+        return new Key(address, deviceId);
     }
 
     private SessionRecord getSessionRecordFromResultSet(ResultSet resultSet) throws SQLException {
     }
 
     private SessionRecord getSessionRecordFromResultSet(ResultSet resultSet) throws SQLException {
@@ -356,19 +346,19 @@ public class SessionStore implements SignalServiceSessionStore {
         }
 
         final var sql = """
         }
 
         final var sql = """
-                        INSERT OR REPLACE INTO %s (account_id_type, uuid, device_id, record)
+                        INSERT OR REPLACE INTO %s (account_id_type, address, device_id, record)
                         VALUES (?, ?, ?, ?)
                         """.formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
                         VALUES (?, ?, ?, ?)
                         """.formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
-            statement.setBytes(2, key.serviceId().toByteArray());
+            statement.setString(2, key.address());
             statement.setInt(3, key.deviceId());
             statement.setBytes(4, session.serialize());
             statement.executeUpdate();
         }
     }
 
             statement.setInt(3, key.deviceId());
             statement.setBytes(4, session.serialize());
             statement.executeUpdate();
         }
     }
 
-    private void deleteAllSessions(final Connection connection, final ServiceId serviceId) throws SQLException {
+    private void deleteAllSessions(final Connection connection, final String address) throws SQLException {
         synchronized (cachedSessions) {
             cachedSessions.clear();
         }
         synchronized (cachedSessions) {
             cachedSessions.clear();
         }
@@ -376,12 +366,12 @@ public class SessionStore implements SignalServiceSessionStore {
         final var sql = (
                 """
                 DELETE FROM %s AS s
         final var sql = (
                 """
                 DELETE FROM %s AS s
-                WHERE s.account_id_type = ? AND s.uuid = ?
+                WHERE s.account_id_type = ? AND s.address = ?
                 """
         ).formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
                 """
         ).formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
-            statement.setBytes(2, serviceId.toByteArray());
+            statement.setString(2, address);
             statement.executeUpdate();
         }
     }
             statement.executeUpdate();
         }
     }
@@ -394,12 +384,12 @@ public class SessionStore implements SignalServiceSessionStore {
         final var sql = (
                 """
                 DELETE FROM %s AS s
         final var sql = (
                 """
                 DELETE FROM %s AS s
-                WHERE s.account_id_type = ? AND s.uuid = ? AND s.device_id = ?
+                WHERE s.account_id_type = ? AND s.address = ? AND s.device_id = ?
                 """
         ).formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
                 """
         ).formatted(TABLE_SESSION);
         try (final var statement = connection.prepareStatement(sql)) {
             statement.setInt(1, accountIdType);
-            statement.setBytes(2, key.serviceId().toByteArray());
+            statement.setString(2, key.address());
             statement.setInt(3, key.deviceId());
             statement.executeUpdate();
         }
             statement.setInt(3, key.deviceId());
             statement.executeUpdate();
         }
@@ -409,5 +399,5 @@ public class SessionStore implements SignalServiceSessionStore {
         return record != null && record.hasSenderChain();
     }
 
         return record != null && record.hasSenderChain();
     }
 
-    record Key(ServiceId serviceId, int deviceId) {}
+    record Key(String address, int deviceId) {}
 }
 }