Update libsignal-service-java

This commit is contained in:
AsamK 2023-10-19 21:36:19 +02:00
parent bf16885278
commit 314159c273
17 changed files with 17 additions and 188 deletions

View file

@ -4,6 +4,8 @@
"pattern":"\\QMETA-INF/maven/org.xerial/sqlite-jdbc/pom.properties\\E" "pattern":"\\QMETA-INF/maven/org.xerial/sqlite-jdbc/pom.properties\\E"
}, { }, {
"pattern":"\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E" "pattern":"\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E"
}, {
"pattern":"\\QMETA-INF/services/com.sun.net.httpserver.spi.HttpServerProvider\\E"
}, { }, {
"pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E" "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E"
}, { }, {

View file

@ -1,11 +1,11 @@
package org.asamk.signal.manager.api; package org.asamk.signal.manager.api;
import org.asamk.signal.manager.groups.GroupLinkPassword; import org.asamk.signal.manager.groups.GroupLinkPassword;
import org.signal.core.util.Base64;
import org.signal.libsignal.zkgroup.InvalidInputException; import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.groups.GroupMasterKey; import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
import org.signal.storageservice.protos.groups.GroupInviteLink; import org.signal.storageservice.protos.groups.GroupInviteLink;
import org.signal.storageservice.protos.groups.local.DecryptedGroup; import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.whispersystems.util.Base64UrlSafe;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@ -49,7 +49,7 @@ public final class GroupInviteLinkUrl {
throw new InvalidGroupLinkException("No reference was in the uri"); throw new InvalidGroupLinkException("No reference was in the uri");
} }
var bytes = Base64UrlSafe.decodePaddingAgnostic(encoding); var bytes = Base64.decode(encoding);
GroupInviteLink groupInviteLink = GroupInviteLink.ADAPTER.decode(bytes); GroupInviteLink groupInviteLink = GroupInviteLink.ADAPTER.decode(bytes);
if (groupInviteLink.v1Contents != null) { if (groupInviteLink.v1Contents != null) {
@ -95,7 +95,7 @@ public final class GroupInviteLinkUrl {
.inviteLinkPassword(ByteString.of(password.serialize())) .inviteLinkPassword(ByteString.of(password.serialize()))
.build()).build(); .build()).build();
var encoding = Base64UrlSafe.encodeBytesWithoutPadding(groupInviteLink.encode()); var encoding = Base64.encodeUrlSafeWithoutPadding(groupInviteLink.encode());
return GROUP_URL_PREFIX + encoding; return GROUP_URL_PREFIX + encoding;
} }

View file

@ -1,18 +0,0 @@
package org.asamk.signal.manager.config;
import org.whispersystems.signalservice.api.push.TrustStore;
import java.io.InputStream;
class IasTrustStore implements TrustStore {
@Override
public InputStream getKeyStoreInputStream() {
return IasTrustStore.class.getResourceAsStream("ias.store");
}
@Override
public String getKeyStorePassword() {
return "whisper";
}
}

View file

@ -1,13 +1,11 @@
package org.asamk.signal.manager.config; package org.asamk.signal.manager.config;
import org.bouncycastle.util.encoders.Hex;
import org.signal.libsignal.protocol.InvalidKeyException; import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.ecc.Curve; import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECPublicKey; import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.push.TrustStore;
import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl;
import org.whispersystems.signalservice.internal.configuration.SignalCdsiUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdsiUrl;
import org.whispersystems.signalservice.internal.configuration.SignalKeyBackupServiceUrl;
import org.whispersystems.signalservice.internal.configuration.SignalProxy; import org.whispersystems.signalservice.internal.configuration.SignalProxy;
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl;
@ -15,7 +13,6 @@ import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl;
import org.whispersystems.signalservice.internal.configuration.SignalSvr2Url; import org.whispersystems.signalservice.internal.configuration.SignalSvr2Url;
import java.util.Base64; import java.util.Base64;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -30,19 +27,9 @@ class LiveConfig {
private final static String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57"; private final static String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57";
private final static String SVR2_MRENCLAVE = "6ee1042f9e20f880326686dd4ba50c25359f01e9f733eeba4382bca001d45094"; private final static String SVR2_MRENCLAVE = "6ee1042f9e20f880326686dd4ba50c25359f01e9f733eeba4382bca001d45094";
private final static String KEY_BACKUP_ENCLAVE_NAME = "e18376436159cda3ad7a45d9320e382e4a497f26b0dca34d8eab0bd0139483b5";
private final static byte[] KEY_BACKUP_SERVICE_ID = Hex.decode(
"3a485adb56e2058ef7737764c738c4069dd62bc457637eafb6bbce1ce29ddb89");
private final static String KEY_BACKUP_MRENCLAVE = "45627094b2ea4a66f4cf0b182858a8dcf4b8479122c3820fe7fd0551a6d4cf5c";
private final static String FALLBACK_KEY_BACKUP_ENCLAVE_NAME = "0cedba03535b41b67729ce9924185f831d7767928a1d1689acb689bc079c375f";
private final static byte[] FALLBACK_KEY_BACKUP_SERVICE_ID = Hex.decode(
"187d2739d22be65e74b65f0055e74d31310e4267e5fac2b1246cc8beba81af39");
private final static String FALLBACK_KEY_BACKUP_MRENCLAVE = "ee19f1965b1eefa3dc4204eb70c04f397755f771b8c1909d080c04dad2a6a9ba";
private final static String URL = "https://chat.signal.org"; private final static String URL = "https://chat.signal.org";
private final static String CDN_URL = "https://cdn.signal.org"; private final static String CDN_URL = "https://cdn.signal.org";
private final static String CDN2_URL = "https://cdn2.signal.org"; private final static String CDN2_URL = "https://cdn2.signal.org";
private final static String SIGNAL_KEY_BACKUP_URL = "https://api.backup.signal.org";
private final static String STORAGE_URL = "https://storage.signal.org"; private final static String STORAGE_URL = "https://storage.signal.org";
private final static String SIGNAL_CDSI_URL = "https://cdsi.signal.org"; private final static String SIGNAL_CDSI_URL = "https://cdsi.signal.org";
private final static String SIGNAL_SVR2_URL = "https://svr2.signal.org"; private final static String SIGNAL_SVR2_URL = "https://svr2.signal.org";
@ -64,7 +51,6 @@ class LiveConfig {
new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)},
2, 2,
new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}), new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}),
new SignalKeyBackupServiceUrl[]{new SignalKeyBackupServiceUrl(SIGNAL_KEY_BACKUP_URL, TRUST_STORE)},
new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)}, new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)},
new SignalCdsiUrl[]{new SignalCdsiUrl(SIGNAL_CDSI_URL, TRUST_STORE)}, new SignalCdsiUrl[]{new SignalCdsiUrl(SIGNAL_CDSI_URL, TRUST_STORE)},
new SignalSvr2Url[]{new SignalSvr2Url(SIGNAL_SVR2_URL, TRUST_STORE, null, null)}, new SignalSvr2Url[]{new SignalSvr2Url(SIGNAL_SVR2_URL, TRUST_STORE, null, null)},
@ -83,16 +69,6 @@ class LiveConfig {
} }
} }
static KeyBackupConfig createKeyBackupConfig() {
return new KeyBackupConfig(KEY_BACKUP_ENCLAVE_NAME, KEY_BACKUP_SERVICE_ID, KEY_BACKUP_MRENCLAVE);
}
static Collection<KeyBackupConfig> createFallbackKeyBackupConfigs() {
return List.of(new KeyBackupConfig(FALLBACK_KEY_BACKUP_ENCLAVE_NAME,
FALLBACK_KEY_BACKUP_SERVICE_ID,
FALLBACK_KEY_BACKUP_MRENCLAVE));
}
static String getCdsiMrenclave() { static String getCdsiMrenclave() {
return CDSI_MRENCLAVE; return CDSI_MRENCLAVE;
} }

View file

@ -3,13 +3,7 @@ package org.asamk.signal.manager.config;
import org.asamk.signal.manager.api.ServiceEnvironment; import org.asamk.signal.manager.api.ServiceEnvironment;
import org.signal.libsignal.protocol.util.Medium; import org.signal.libsignal.protocol.util.Medium;
import org.whispersystems.signalservice.api.account.AccountAttributes; import org.whispersystems.signalservice.api.account.AccountAttributes;
import org.whispersystems.signalservice.api.push.TrustStore;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -31,31 +25,11 @@ public class ServiceConfig {
public final static int GROUP_MAX_SIZE = 1001; public final static int GROUP_MAX_SIZE = 1001;
public final static int MAXIMUM_ONE_OFF_REQUEST_SIZE = 3; public final static int MAXIMUM_ONE_OFF_REQUEST_SIZE = 3;
private final static KeyStore iasKeyStore;
static {
try {
TrustStore contactTrustStore = new IasTrustStore();
var keyStore = KeyStore.getInstance("BKS");
keyStore.load(contactTrustStore.getKeyStoreInputStream(),
contactTrustStore.getKeyStorePassword().toCharArray());
iasKeyStore = keyStore;
} catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}
public static AccountAttributes.Capabilities getCapabilities(boolean isPrimaryDevice) { public static AccountAttributes.Capabilities getCapabilities(boolean isPrimaryDevice) {
final var giftBadges = !isPrimaryDevice; final var giftBadges = !isPrimaryDevice;
return new AccountAttributes.Capabilities(false, true, true, true, true, giftBadges, false, false); return new AccountAttributes.Capabilities(false, true, true, true, true, giftBadges, false, false);
} }
public static KeyStore getIasKeyStore() {
return iasKeyStore;
}
public static ServiceEnvironmentConfig getServiceEnvironmentConfig( public static ServiceEnvironmentConfig getServiceEnvironmentConfig(
ServiceEnvironment serviceEnvironment, String userAgent ServiceEnvironment serviceEnvironment, String userAgent
) { ) {
@ -70,15 +44,11 @@ public class ServiceConfig {
case LIVE -> new ServiceEnvironmentConfig(serviceEnvironment, case LIVE -> new ServiceEnvironmentConfig(serviceEnvironment,
LiveConfig.createDefaultServiceConfiguration(interceptors), LiveConfig.createDefaultServiceConfiguration(interceptors),
LiveConfig.getUnidentifiedSenderTrustRoot(), LiveConfig.getUnidentifiedSenderTrustRoot(),
LiveConfig.createKeyBackupConfig(),
LiveConfig.createFallbackKeyBackupConfigs(),
LiveConfig.getCdsiMrenclave(), LiveConfig.getCdsiMrenclave(),
LiveConfig.getSvr2Mrenclave()); LiveConfig.getSvr2Mrenclave());
case STAGING -> new ServiceEnvironmentConfig(serviceEnvironment, case STAGING -> new ServiceEnvironmentConfig(serviceEnvironment,
StagingConfig.createDefaultServiceConfiguration(interceptors), StagingConfig.createDefaultServiceConfiguration(interceptors),
StagingConfig.getUnidentifiedSenderTrustRoot(), StagingConfig.getUnidentifiedSenderTrustRoot(),
StagingConfig.createKeyBackupConfig(),
StagingConfig.createFallbackKeyBackupConfigs(),
StagingConfig.getCdsiMrenclave(), StagingConfig.getCdsiMrenclave(),
StagingConfig.getSvr2Mrenclave()); StagingConfig.getSvr2Mrenclave());
}; };

View file

@ -4,14 +4,10 @@ import org.asamk.signal.manager.api.ServiceEnvironment;
import org.signal.libsignal.protocol.ecc.ECPublicKey; import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import java.util.Collection;
public record ServiceEnvironmentConfig( public record ServiceEnvironmentConfig(
ServiceEnvironment type, ServiceEnvironment type,
SignalServiceConfiguration signalServiceConfiguration, SignalServiceConfiguration signalServiceConfiguration,
ECPublicKey unidentifiedSenderTrustRoot, ECPublicKey unidentifiedSenderTrustRoot,
KeyBackupConfig keyBackupConfig,
Collection<KeyBackupConfig> fallbackKeyBackupConfigs,
String cdsiMrenclave, String cdsiMrenclave,
String svr2Mrenclave String svr2Mrenclave
) {} ) {}

View file

@ -1,13 +1,11 @@
package org.asamk.signal.manager.config; package org.asamk.signal.manager.config;
import org.bouncycastle.util.encoders.Hex;
import org.signal.libsignal.protocol.InvalidKeyException; import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.ecc.Curve; import org.signal.libsignal.protocol.ecc.Curve;
import org.signal.libsignal.protocol.ecc.ECPublicKey; import org.signal.libsignal.protocol.ecc.ECPublicKey;
import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.push.TrustStore;
import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl;
import org.whispersystems.signalservice.internal.configuration.SignalCdsiUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdsiUrl;
import org.whispersystems.signalservice.internal.configuration.SignalKeyBackupServiceUrl;
import org.whispersystems.signalservice.internal.configuration.SignalProxy; import org.whispersystems.signalservice.internal.configuration.SignalProxy;
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl;
@ -15,7 +13,6 @@ import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl;
import org.whispersystems.signalservice.internal.configuration.SignalSvr2Url; import org.whispersystems.signalservice.internal.configuration.SignalSvr2Url;
import java.util.Base64; import java.util.Base64;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -30,19 +27,9 @@ class StagingConfig {
private final static String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57"; private final static String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57";
private final static String SVR2_MRENCLAVE = "a8a261420a6bb9b61aa25bf8a79e8bd20d7652531feb3381cbffd446d270be95"; private final static String SVR2_MRENCLAVE = "a8a261420a6bb9b61aa25bf8a79e8bd20d7652531feb3381cbffd446d270be95";
private final static String KEY_BACKUP_ENCLAVE_NAME = "39963b736823d5780be96ab174869a9499d56d66497aa8f9b2244f777ebc366b";
private final static byte[] KEY_BACKUP_SERVICE_ID = Hex.decode(
"ee1d0d972b7ea903615670de43ab1b6e7a825e811c70a29bb5fe0f819e0975fa");
private final static String KEY_BACKUP_MRENCLAVE = "45627094b2ea4a66f4cf0b182858a8dcf4b8479122c3820fe7fd0551a6d4cf5c";
private final static String FALLBACK_KEY_BACKUP_ENCLAVE_NAME = "dd6f66d397d9e8cf6ec6db238e59a7be078dd50e9715427b9c89b409ffe53f99";
private final static byte[] FALLBACK_KEY_BACKUP_SERVICE_ID = Hex.decode(
"4200003414528c151e2dccafbc87aa6d3d66a5eb8f8c05979a6e97cb33cd493a");
private final static String FALLBACK_KEY_BACKUP_MRENCLAVE = "ee19f1965b1eefa3dc4204eb70c04f397755f771b8c1909d080c04dad2a6a9ba";
private final static String URL = "https://chat.staging.signal.org"; private final static String URL = "https://chat.staging.signal.org";
private final static String CDN_URL = "https://cdn-staging.signal.org"; private final static String CDN_URL = "https://cdn-staging.signal.org";
private final static String CDN2_URL = "https://cdn2-staging.signal.org"; private final static String CDN2_URL = "https://cdn2-staging.signal.org";
private final static String SIGNAL_KEY_BACKUP_URL = "https://api-staging.backup.signal.org";
private final static String STORAGE_URL = "https://storage-staging.signal.org"; private final static String STORAGE_URL = "https://storage-staging.signal.org";
private final static String SIGNAL_CDSI_URL = "https://cdsi.staging.signal.org"; private final static String SIGNAL_CDSI_URL = "https://cdsi.staging.signal.org";
private final static String SIGNAL_SVR2_URL = "https://svr2.staging.signal.org"; private final static String SIGNAL_SVR2_URL = "https://svr2.staging.signal.org";
@ -64,7 +51,6 @@ class StagingConfig {
new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)},
2, 2,
new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}), new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}),
new SignalKeyBackupServiceUrl[]{new SignalKeyBackupServiceUrl(SIGNAL_KEY_BACKUP_URL, TRUST_STORE)},
new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)}, new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)},
new SignalCdsiUrl[]{new SignalCdsiUrl(SIGNAL_CDSI_URL, TRUST_STORE)}, new SignalCdsiUrl[]{new SignalCdsiUrl(SIGNAL_CDSI_URL, TRUST_STORE)},
new SignalSvr2Url[]{new SignalSvr2Url(SIGNAL_SVR2_URL, TRUST_STORE, null, null)}, new SignalSvr2Url[]{new SignalSvr2Url(SIGNAL_SVR2_URL, TRUST_STORE, null, null)},
@ -83,16 +69,6 @@ class StagingConfig {
} }
} }
static KeyBackupConfig createKeyBackupConfig() {
return new KeyBackupConfig(KEY_BACKUP_ENCLAVE_NAME, KEY_BACKUP_SERVICE_ID, KEY_BACKUP_MRENCLAVE);
}
static Collection<KeyBackupConfig> createFallbackKeyBackupConfigs() {
return List.of(new KeyBackupConfig(FALLBACK_KEY_BACKUP_ENCLAVE_NAME,
FALLBACK_KEY_BACKUP_SERVICE_ID,
FALLBACK_KEY_BACKUP_MRENCLAVE));
}
static String getCdsiMrenclave() { static String getCdsiMrenclave() {
return CDSI_MRENCLAVE; return CDSI_MRENCLAVE;
} }

View file

@ -12,6 +12,7 @@ import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.util.KeyUtils; import org.asamk.signal.manager.util.KeyUtils;
import org.asamk.signal.manager.util.NumberVerificationUtils; import org.asamk.signal.manager.util.NumberVerificationUtils;
import org.asamk.signal.manager.util.Utils; import org.asamk.signal.manager.util.Utils;
import org.signal.core.util.Base64;
import org.signal.libsignal.protocol.IdentityKeyPair; import org.signal.libsignal.protocol.IdentityKeyPair;
import org.signal.libsignal.protocol.InvalidKeyException; import org.signal.libsignal.protocol.InvalidKeyException;
import org.signal.libsignal.protocol.SignalProtocolAddress; import org.signal.libsignal.protocol.SignalProtocolAddress;
@ -37,7 +38,6 @@ import org.whispersystems.signalservice.internal.push.KyberPreKeyEntity;
import org.whispersystems.signalservice.internal.push.OutgoingPushMessage; import org.whispersystems.signalservice.internal.push.OutgoingPushMessage;
import org.whispersystems.signalservice.internal.push.SyncMessage; import org.whispersystems.signalservice.internal.push.SyncMessage;
import org.whispersystems.signalservice.internal.push.exceptions.MismatchedDevicesException; import org.whispersystems.signalservice.internal.push.exceptions.MismatchedDevicesException;
import org.whispersystems.util.Base64UrlSafe;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -318,7 +318,7 @@ public class AccountHelper {
final var candidates = Username.candidatesFrom(nickname, USERNAME_MIN_LENGTH, USERNAME_MAX_LENGTH); final var candidates = Username.candidatesFrom(nickname, USERNAME_MIN_LENGTH, USERNAME_MAX_LENGTH);
final var candidateHashes = new ArrayList<String>(); final var candidateHashes = new ArrayList<String>();
for (final var candidate : candidates) { for (final var candidate : candidates) {
candidateHashes.add(Base64UrlSafe.encodeBytesWithoutPadding(candidate.getHash())); candidateHashes.add(Base64.encodeUrlSafeWithoutPadding(candidate.getHash()));
} }
final var response = dependencies.getAccountManager().reserveUsername(candidateHashes); final var response = dependencies.getAccountManager().reserveUsername(candidateHashes);
@ -348,7 +348,7 @@ public class AccountHelper {
final var whoAmIResponse = dependencies.getAccountManager().getWhoAmI(); final var whoAmIResponse = dependencies.getAccountManager().getWhoAmI();
final var serverUsernameHash = whoAmIResponse.getUsernameHash(); final var serverUsernameHash = whoAmIResponse.getUsernameHash();
final var hasServerUsername = !isEmpty(serverUsernameHash); final var hasServerUsername = !isEmpty(serverUsernameHash);
final var localUsernameHash = Base64UrlSafe.encodeBytesWithoutPadding(new Username(localUsername).getHash()); final var localUsernameHash = Base64.encodeUrlSafeWithoutPadding(new Username(localUsername).getHash());
if (!hasServerUsername) { if (!hasServerUsername) {
logger.debug("No remote username is set."); logger.debug("No remote username is set.");

View file

@ -6,7 +6,6 @@ import org.asamk.signal.manager.storage.AttachmentStore;
import org.asamk.signal.manager.storage.AvatarStore; import org.asamk.signal.manager.storage.AvatarStore;
import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.stickerPacks.StickerPackStore; import org.asamk.signal.manager.storage.stickerPacks.StickerPackStore;
import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV1;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -115,10 +114,7 @@ public class Context {
} }
PinHelper getPinHelper() { PinHelper getPinHelper() {
return getOrCreate(() -> pinHelper, return getOrCreate(() -> pinHelper, () -> pinHelper = new PinHelper(dependencies.getSecureValueRecoveryV2()));
() -> pinHelper = new PinHelper(new SecureValueRecoveryV1(dependencies.getKeyBackupService()),
dependencies.getSecureValueRecoveryV2(),
dependencies.getFallbackKeyBackupServices()));
} }
public PreKeyHelper getPreKeyHelper() { public PreKeyHelper getPreKeyHelper() {

View file

@ -3,39 +3,27 @@ package org.asamk.signal.manager.helper;
import org.asamk.signal.manager.api.IncorrectPinException; import org.asamk.signal.manager.api.IncorrectPinException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.signalservice.api.KeyBackupService;
import org.whispersystems.signalservice.api.kbs.MasterKey; import org.whispersystems.signalservice.api.kbs.MasterKey;
import org.whispersystems.signalservice.api.svr.SecureValueRecovery; import org.whispersystems.signalservice.api.svr.SecureValueRecovery;
import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV1;
import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV2; import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV2;
import org.whispersystems.signalservice.internal.push.AuthCredentials; import org.whispersystems.signalservice.internal.push.AuthCredentials;
import org.whispersystems.signalservice.internal.push.LockedException; import org.whispersystems.signalservice.internal.push.LockedException;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
public class PinHelper { public class PinHelper {
private final static Logger logger = LoggerFactory.getLogger(PinHelper.class); private final static Logger logger = LoggerFactory.getLogger(PinHelper.class);
private final SecureValueRecoveryV1 secureValueRecoveryV1;
private final SecureValueRecoveryV2 secureValueRecoveryV2; private final SecureValueRecoveryV2 secureValueRecoveryV2;
private final Collection<KeyBackupService> fallbackKeyBackupServices;
public PinHelper( public PinHelper(final SecureValueRecoveryV2 secureValueRecoveryV2) {
final SecureValueRecoveryV1 secureValueRecoveryV1,
final SecureValueRecoveryV2 secureValueRecoveryV2,
final Collection<KeyBackupService> fallbackKeyBackupServices
) {
this.fallbackKeyBackupServices = fallbackKeyBackupServices;
this.secureValueRecoveryV1 = secureValueRecoveryV1;
this.secureValueRecoveryV2 = secureValueRecoveryV2; this.secureValueRecoveryV2 = secureValueRecoveryV2;
} }
public void setRegistrationLockPin( public void setRegistrationLockPin(
String pin, MasterKey masterKey String pin, MasterKey masterKey
) throws IOException { ) throws IOException {
secureValueRecoveryV1.setPin(pin, masterKey).execute();
final var backupResponse = secureValueRecoveryV2.setPin(pin, masterKey).execute(); final var backupResponse = secureValueRecoveryV2.setPin(pin, masterKey).execute();
if (backupResponse instanceof SecureValueRecovery.BackupResponse.Success) { if (backupResponse instanceof SecureValueRecovery.BackupResponse.Success) {
} else if (backupResponse instanceof SecureValueRecovery.BackupResponse.ServerRejected) { } else if (backupResponse instanceof SecureValueRecovery.BackupResponse.ServerRejected) {
@ -55,19 +43,9 @@ public class PinHelper {
public void migrateRegistrationLockPin(String pin, MasterKey masterKey) throws IOException { public void migrateRegistrationLockPin(String pin, MasterKey masterKey) throws IOException {
setRegistrationLockPin(pin, masterKey); setRegistrationLockPin(pin, masterKey);
for (final var keyBackupService : fallbackKeyBackupServices) {
try {
final var pinChangeSession = keyBackupService.newPinChangeSession();
pinChangeSession.removePin();
} catch (Exception e) {
logger.warn("Failed to remove PIN from fallback KBS: {}", e.getMessage());
}
}
} }
public void removeRegistrationLockPin() throws IOException { public void removeRegistrationLockPin() throws IOException {
secureValueRecoveryV1.deleteData();
final var deleteResponse = secureValueRecoveryV2.deleteData(); final var deleteResponse = secureValueRecoveryV2.deleteData();
if (deleteResponse instanceof SecureValueRecovery.DeleteResponse.Success) { if (deleteResponse instanceof SecureValueRecovery.DeleteResponse.Success) {
} else if (deleteResponse instanceof SecureValueRecovery.DeleteResponse.ServerRejected) { } else if (deleteResponse instanceof SecureValueRecovery.DeleteResponse.ServerRejected) {
@ -86,14 +64,6 @@ public class PinHelper {
public SecureValueRecovery.RestoreResponse.Success getRegistrationLockData( public SecureValueRecovery.RestoreResponse.Success getRegistrationLockData(
String pin, LockedException e String pin, LockedException e
) throws IOException, IncorrectPinException { ) throws IOException, IncorrectPinException {
var svr1Credentials = e.getSvr1Credentials();
if (svr1Credentials != null) {
final var registrationLockData = getRegistrationLockData(secureValueRecoveryV1, svr1Credentials, pin);
if (registrationLockData != null) {
return registrationLockData;
}
}
var svr2Credentials = e.getSvr2Credentials(); var svr2Credentials = e.getSvr2Credentials();
if (svr2Credentials != null) { if (svr2Credentials != null) {
return getRegistrationLockData(secureValueRecoveryV2, svr2Credentials, pin); return getRegistrationLockData(secureValueRecoveryV2, svr2Credentials, pin);

View file

@ -6,6 +6,7 @@ import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
import org.asamk.signal.manager.internal.SignalDependencies; import org.asamk.signal.manager.internal.SignalDependencies;
import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.signal.core.util.Base64;
import org.signal.libsignal.usernames.BaseUsernameException; import org.signal.libsignal.usernames.BaseUsernameException;
import org.signal.libsignal.usernames.Username; import org.signal.libsignal.usernames.Username;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -16,7 +17,6 @@ import org.whispersystems.signalservice.api.push.ServiceId.PNI;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidTokenException; import org.whispersystems.signalservice.api.push.exceptions.CdsiInvalidTokenException;
import org.whispersystems.signalservice.api.services.CdsiV2Service; import org.whispersystems.signalservice.api.services.CdsiV2Service;
import org.whispersystems.util.Base64UrlSafe;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
@ -235,7 +235,7 @@ public class RecipientHelper {
private ACI getRegisteredUserByUsername(String username) throws IOException, BaseUsernameException { private ACI getRegisteredUserByUsername(String username) throws IOException, BaseUsernameException {
return dependencies.getAccountManager() return dependencies.getAccountManager()
.getAciByUsernameHash(Base64UrlSafe.encodeBytesWithoutPadding(new Username(username).getHash())); .getAciByUsernameHash(Base64.encodeUrlSafeWithoutPadding(new Username(username).getHash()));
} }
public record RegisteredUser(Optional<ACI> aci, Optional<PNI> pni) { public record RegisteredUser(Optional<ACI> aci, Optional<PNI> pni) {

View file

@ -257,8 +257,7 @@ public class StorageHelper {
account.getConfigurationStore().setLinkPreviews(accountRecord.isLinkPreviewsEnabled()); account.getConfigurationStore().setLinkPreviews(accountRecord.isLinkPreviewsEnabled());
account.getConfigurationStore().setPhoneNumberSharingMode(switch (accountRecord.getPhoneNumberSharingMode()) { account.getConfigurationStore().setPhoneNumberSharingMode(switch (accountRecord.getPhoneNumberSharingMode()) {
case EVERYBODY -> PhoneNumberSharingMode.EVERYBODY; case EVERYBODY -> PhoneNumberSharingMode.EVERYBODY;
case NOBODY -> PhoneNumberSharingMode.NOBODY; case NOBODY, UNKNOWN -> PhoneNumberSharingMode.NOBODY;
case CONTACTS_ONLY -> PhoneNumberSharingMode.CONTACTS;
}); });
account.getConfigurationStore().setPhoneNumberUnlisted(accountRecord.isPhoneNumberUnlisted()); account.getConfigurationStore().setPhoneNumberUnlisted(accountRecord.isPhoneNumberUnlisted());
account.setUsername(accountRecord.getUsername()); account.setUsername(accountRecord.getUsername());

View file

@ -222,7 +222,8 @@ public class SyncHelper {
} }
public SendMessageResult sendKeysMessage() { public SendMessageResult sendKeysMessage() {
var keysMessage = new KeysMessage(Optional.ofNullable(account.getStorageKey())); var keysMessage = new KeysMessage(Optional.ofNullable(account.getStorageKey()),
Optional.ofNullable(account.getOrCreatePinMasterKey()));
return context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage)); return context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage));
} }

View file

@ -45,7 +45,6 @@ import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException; import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException;
import org.whispersystems.signalservice.api.push.exceptions.DeprecatedVersionException; import org.whispersystems.signalservice.api.push.exceptions.DeprecatedVersionException;
import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV1;
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse; import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider; import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
@ -95,23 +94,8 @@ public class RegistrationManagerImpl implements RegistrationManager {
userAgent, userAgent,
groupsV2Operations, groupsV2Operations,
ServiceConfig.AUTOMATIC_NETWORK_RETRY); ServiceConfig.AUTOMATIC_NETWORK_RETRY);
final var keyBackupService = accountManager.getKeyBackupService(ServiceConfig.getIasKeyStore(),
serviceEnvironmentConfig.keyBackupConfig().enclaveName(),
serviceEnvironmentConfig.keyBackupConfig().serviceId(),
serviceEnvironmentConfig.keyBackupConfig().mrenclave(),
10);
final var fallbackKeyBackupServices = serviceEnvironmentConfig.fallbackKeyBackupConfigs()
.stream()
.map(config -> accountManager.getKeyBackupService(ServiceConfig.getIasKeyStore(),
config.enclaveName(),
config.serviceId(),
config.mrenclave(),
10))
.toList();
final var secureValueRecoveryV2 = accountManager.getSecureValueRecoveryV2(serviceEnvironmentConfig.svr2Mrenclave()); final var secureValueRecoveryV2 = accountManager.getSecureValueRecoveryV2(serviceEnvironmentConfig.svr2Mrenclave());
this.pinHelper = new PinHelper(new SecureValueRecoveryV1(keyBackupService), this.pinHelper = new PinHelper(secureValueRecoveryV2);
secureValueRecoveryV2,
fallbackKeyBackupServices);
} }
@Override @Override

View file

@ -4,7 +4,6 @@ import org.asamk.signal.manager.config.ServiceConfig;
import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
import org.signal.libsignal.metadata.certificate.CertificateValidator; import org.signal.libsignal.metadata.certificate.CertificateValidator;
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
import org.whispersystems.signalservice.api.KeyBackupService;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.SignalServiceDataStore; import org.whispersystems.signalservice.api.SignalServiceDataStore;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
@ -23,7 +22,6 @@ import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
import org.whispersystems.signalservice.api.websocket.WebSocketFactory; import org.whispersystems.signalservice.api.websocket.WebSocketFactory;
import org.whispersystems.signalservice.internal.websocket.WebSocketConnection; import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -50,7 +48,6 @@ public class SignalDependencies {
private SignalServiceMessageReceiver messageReceiver; private SignalServiceMessageReceiver messageReceiver;
private SignalServiceMessageSender messageSender; private SignalServiceMessageSender messageSender;
private KeyBackupService keyBackupService;
private SecureValueRecoveryV2 secureValueRecoveryV2; private SecureValueRecoveryV2 secureValueRecoveryV2;
private ProfileService profileService; private ProfileService profileService;
private SignalServiceCipher cipher; private SignalServiceCipher cipher;
@ -187,31 +184,11 @@ public class SignalDependencies {
ServiceConfig.AUTOMATIC_NETWORK_RETRY)); ServiceConfig.AUTOMATIC_NETWORK_RETRY));
} }
public KeyBackupService getKeyBackupService() {
return getOrCreate(() -> keyBackupService,
() -> keyBackupService = getAccountManager().getKeyBackupService(ServiceConfig.getIasKeyStore(),
serviceEnvironmentConfig.keyBackupConfig().enclaveName(),
serviceEnvironmentConfig.keyBackupConfig().serviceId(),
serviceEnvironmentConfig.keyBackupConfig().mrenclave(),
10));
}
public SecureValueRecoveryV2 getSecureValueRecoveryV2() { public SecureValueRecoveryV2 getSecureValueRecoveryV2() {
return getOrCreate(() -> secureValueRecoveryV2, return getOrCreate(() -> secureValueRecoveryV2,
() -> secureValueRecoveryV2 = getAccountManager().getSecureValueRecoveryV2(serviceEnvironmentConfig.svr2Mrenclave())); () -> secureValueRecoveryV2 = getAccountManager().getSecureValueRecoveryV2(serviceEnvironmentConfig.svr2Mrenclave()));
} }
public Collection<KeyBackupService> getFallbackKeyBackupServices() {
return serviceEnvironmentConfig.fallbackKeyBackupConfigs()
.stream()
.map(config -> getAccountManager().getKeyBackupService(ServiceConfig.getIasKeyStore(),
config.enclaveName(),
config.serviceId(),
config.mrenclave(),
10))
.toList();
}
public ProfileService getProfileService() { public ProfileService getProfileService() {
return getOrCreate(() -> profileService, return getOrCreate(() -> profileService,
() -> profileService = new ProfileService(getClientZkProfileOperations(), () -> profileService = new ProfileService(getClientZkProfileOperations(),

View file

@ -16,7 +16,7 @@ dependencyResolutionManagement {
library("logback", "ch.qos.logback", "logback-classic").version("1.4.11") library("logback", "ch.qos.logback", "logback-classic").version("1.4.11")
library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_85") library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_86")
library("sqlite", "org.xerial", "sqlite-jdbc").version("3.43.2.0") library("sqlite", "org.xerial", "sqlite-jdbc").version("3.43.2.0")
library("hikari", "com.zaxxer", "HikariCP").version("5.0.1") library("hikari", "com.zaxxer", "HikariCP").version("5.0.1")
library("junit", "org.junit.jupiter", "junit-jupiter").version("5.10.0") library("junit", "org.junit.jupiter", "junit-jupiter").version("5.10.0")