mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Use a new SVR2 enclave.
This commit is contained in:
parent
2535cd9c2c
commit
4dcdffda0a
7 changed files with 99 additions and 61 deletions
|
@ -20,12 +20,15 @@ import java.util.Optional;
|
|||
import okhttp3.Dns;
|
||||
import okhttp3.Interceptor;
|
||||
|
||||
import static org.asamk.signal.manager.api.ServiceEnvironment.LIVE;
|
||||
|
||||
class LiveConfig {
|
||||
|
||||
private static final byte[] UNIDENTIFIED_SENDER_TRUST_ROOT = Base64.getDecoder()
|
||||
.decode("BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF");
|
||||
private static final String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57";
|
||||
private static final String SVR2_MRENCLAVE = "6ee1042f9e20f880326686dd4ba50c25359f01e9f733eeba4382bca001d45094";
|
||||
private static final String SVR2_MRENCLAVE = "a6622ad4656e1abcd0bc0ff17c229477747d2ded0495c4ebee7ed35c1789fa97";
|
||||
private static final String SVR2_MRENCLAVE_DEPRECATED = "6ee1042f9e20f880326686dd4ba50c25359f01e9f733eeba4382bca001d45094";
|
||||
|
||||
private static final String URL = "https://chat.signal.org";
|
||||
private static final String CDN_URL = "https://cdn.signal.org";
|
||||
|
@ -69,12 +72,12 @@ class LiveConfig {
|
|||
}
|
||||
}
|
||||
|
||||
static String getCdsiMrenclave() {
|
||||
return CDSI_MRENCLAVE;
|
||||
}
|
||||
|
||||
static String getSvr2Mrenclave() {
|
||||
return SVR2_MRENCLAVE;
|
||||
static ServiceEnvironmentConfig getServiceEnvironmentConfig(List<Interceptor> interceptors) {
|
||||
return new ServiceEnvironmentConfig(LIVE,
|
||||
createDefaultServiceConfiguration(interceptors),
|
||||
getUnidentifiedSenderTrustRoot(),
|
||||
CDSI_MRENCLAVE,
|
||||
List.of(SVR2_MRENCLAVE, SVR2_MRENCLAVE_DEPRECATED));
|
||||
}
|
||||
|
||||
private LiveConfig() {
|
||||
|
|
|
@ -43,16 +43,8 @@ public class ServiceConfig {
|
|||
final var interceptors = List.of(userAgentInterceptor);
|
||||
|
||||
return switch (serviceEnvironment) {
|
||||
case LIVE -> new ServiceEnvironmentConfig(serviceEnvironment,
|
||||
LiveConfig.createDefaultServiceConfiguration(interceptors),
|
||||
LiveConfig.getUnidentifiedSenderTrustRoot(),
|
||||
LiveConfig.getCdsiMrenclave(),
|
||||
LiveConfig.getSvr2Mrenclave());
|
||||
case STAGING -> new ServiceEnvironmentConfig(serviceEnvironment,
|
||||
StagingConfig.createDefaultServiceConfiguration(interceptors),
|
||||
StagingConfig.getUnidentifiedSenderTrustRoot(),
|
||||
StagingConfig.getCdsiMrenclave(),
|
||||
StagingConfig.getSvr2Mrenclave());
|
||||
case LIVE -> LiveConfig.getServiceEnvironmentConfig(interceptors);
|
||||
case STAGING -> StagingConfig.getServiceEnvironmentConfig(interceptors);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@ import org.asamk.signal.manager.api.ServiceEnvironment;
|
|||
import org.signal.libsignal.protocol.ecc.ECPublicKey;
|
||||
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record ServiceEnvironmentConfig(
|
||||
ServiceEnvironment type,
|
||||
SignalServiceConfiguration signalServiceConfiguration,
|
||||
ECPublicKey unidentifiedSenderTrustRoot,
|
||||
String cdsiMrenclave,
|
||||
String svr2Mrenclave
|
||||
List<String> svr2Mrenclaves
|
||||
) {}
|
||||
|
|
|
@ -20,12 +20,15 @@ import java.util.Optional;
|
|||
import okhttp3.Dns;
|
||||
import okhttp3.Interceptor;
|
||||
|
||||
import static org.asamk.signal.manager.api.ServiceEnvironment.STAGING;
|
||||
|
||||
class StagingConfig {
|
||||
|
||||
private static final byte[] UNIDENTIFIED_SENDER_TRUST_ROOT = Base64.getDecoder()
|
||||
.decode("BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx");
|
||||
private static final String CDSI_MRENCLAVE = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57";
|
||||
private static final String SVR2_MRENCLAVE = "a8a261420a6bb9b61aa25bf8a79e8bd20d7652531feb3381cbffd446d270be95";
|
||||
private static final String SVR2_MRENCLAVE = "acb1973aa0bbbd14b3b4e06f145497d948fd4a98efc500fcce363b3b743ec482";
|
||||
private static final String SVR2_MRENCLAVE_DEPRECATED = "a8a261420a6bb9b61aa25bf8a79e8bd20d7652531feb3381cbffd446d270be95";
|
||||
|
||||
private static final String URL = "https://chat.staging.signal.org";
|
||||
private static final String CDN_URL = "https://cdn-staging.signal.org";
|
||||
|
@ -69,12 +72,12 @@ class StagingConfig {
|
|||
}
|
||||
}
|
||||
|
||||
static String getCdsiMrenclave() {
|
||||
return CDSI_MRENCLAVE;
|
||||
}
|
||||
|
||||
static String getSvr2Mrenclave() {
|
||||
return SVR2_MRENCLAVE;
|
||||
static ServiceEnvironmentConfig getServiceEnvironmentConfig(List<Interceptor> interceptors) {
|
||||
return new ServiceEnvironmentConfig(STAGING,
|
||||
createDefaultServiceConfiguration(interceptors),
|
||||
getUnidentifiedSenderTrustRoot(),
|
||||
CDSI_MRENCLAVE,
|
||||
List.of(SVR2_MRENCLAVE, SVR2_MRENCLAVE_DEPRECATED));
|
||||
}
|
||||
|
||||
private StagingConfig() {
|
||||
|
|
|
@ -5,39 +5,49 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.kbs.MasterKey;
|
||||
import org.whispersystems.signalservice.api.svr.SecureValueRecovery;
|
||||
import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV2;
|
||||
import org.whispersystems.signalservice.internal.push.AuthCredentials;
|
||||
import org.whispersystems.signalservice.internal.push.LockedException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class PinHelper {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PinHelper.class);
|
||||
|
||||
private final SecureValueRecoveryV2 secureValueRecoveryV2;
|
||||
private final List<SecureValueRecovery> secureValueRecoveries;
|
||||
|
||||
public PinHelper(final SecureValueRecoveryV2 secureValueRecoveryV2) {
|
||||
this.secureValueRecoveryV2 = secureValueRecoveryV2;
|
||||
public PinHelper(final List<SecureValueRecovery> secureValueRecoveries) {
|
||||
this.secureValueRecoveries = secureValueRecoveries;
|
||||
}
|
||||
|
||||
public void setRegistrationLockPin(
|
||||
String pin, MasterKey masterKey
|
||||
) throws IOException {
|
||||
final var backupResponse = secureValueRecoveryV2.setPin(pin, masterKey).execute();
|
||||
switch (backupResponse) {
|
||||
case SecureValueRecovery.BackupResponse.Success success -> {
|
||||
IOException exception = null;
|
||||
for (final var secureValueRecovery : secureValueRecoveries) {
|
||||
try {
|
||||
final var backupResponse = secureValueRecovery.setPin(pin, masterKey).execute();
|
||||
switch (backupResponse) {
|
||||
case SecureValueRecovery.BackupResponse.Success success -> {
|
||||
}
|
||||
case SecureValueRecovery.BackupResponse.ServerRejected serverRejected ->
|
||||
logger.warn("Backup svr2 failed: ServerRejected");
|
||||
case SecureValueRecovery.BackupResponse.EnclaveNotFound enclaveNotFound ->
|
||||
logger.warn("Backup svr2 failed: EnclaveNotFound");
|
||||
case SecureValueRecovery.BackupResponse.ExposeFailure exposeFailure ->
|
||||
logger.warn("Backup svr2 failed: ExposeFailure");
|
||||
case SecureValueRecovery.BackupResponse.ApplicationError error ->
|
||||
throw new IOException(error.getException());
|
||||
case SecureValueRecovery.BackupResponse.NetworkError error -> throw error.getException();
|
||||
case null, default -> throw new AssertionError("Unexpected response");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
case SecureValueRecovery.BackupResponse.ServerRejected serverRejected ->
|
||||
logger.warn("Backup svr2 failed: ServerRejected");
|
||||
case SecureValueRecovery.BackupResponse.EnclaveNotFound enclaveNotFound ->
|
||||
logger.warn("Backup svr2 failed: EnclaveNotFound");
|
||||
case SecureValueRecovery.BackupResponse.ExposeFailure exposeFailure ->
|
||||
logger.warn("Backup svr2 failed: ExposeFailure");
|
||||
case SecureValueRecovery.BackupResponse.ApplicationError error ->
|
||||
throw new IOException(error.getException());
|
||||
case SecureValueRecovery.BackupResponse.NetworkError error -> throw error.getException();
|
||||
case null, default -> throw new AssertionError("Unexpected response");
|
||||
}
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,27 +56,47 @@ public class PinHelper {
|
|||
}
|
||||
|
||||
public void removeRegistrationLockPin() throws IOException {
|
||||
final var deleteResponse = secureValueRecoveryV2.deleteData();
|
||||
switch (deleteResponse) {
|
||||
case SecureValueRecovery.DeleteResponse.Success success -> {
|
||||
IOException exception = null;
|
||||
for (final var secureValueRecovery : secureValueRecoveries) {
|
||||
try {
|
||||
final var deleteResponse = secureValueRecovery.deleteData();
|
||||
switch (deleteResponse) {
|
||||
case SecureValueRecovery.DeleteResponse.Success success -> {
|
||||
}
|
||||
case SecureValueRecovery.DeleteResponse.ServerRejected serverRejected ->
|
||||
logger.warn("Delete svr2 failed: ServerRejected");
|
||||
case SecureValueRecovery.DeleteResponse.EnclaveNotFound enclaveNotFound ->
|
||||
logger.warn("Delete svr2 failed: EnclaveNotFound");
|
||||
case SecureValueRecovery.DeleteResponse.ApplicationError error ->
|
||||
throw new IOException(error.getException());
|
||||
case SecureValueRecovery.DeleteResponse.NetworkError error -> throw error.getException();
|
||||
case null, default -> throw new AssertionError("Unexpected response");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
case SecureValueRecovery.DeleteResponse.ServerRejected serverRejected ->
|
||||
logger.warn("Delete svr2 failed: ServerRejected");
|
||||
case SecureValueRecovery.DeleteResponse.EnclaveNotFound enclaveNotFound ->
|
||||
logger.warn("Delete svr2 failed: EnclaveNotFound");
|
||||
case SecureValueRecovery.DeleteResponse.ApplicationError error ->
|
||||
throw new IOException(error.getException());
|
||||
case SecureValueRecovery.DeleteResponse.NetworkError error -> throw error.getException();
|
||||
case null, default -> throw new AssertionError("Unexpected response");
|
||||
}
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
public SecureValueRecovery.RestoreResponse.Success getRegistrationLockData(
|
||||
String pin, LockedException e
|
||||
String pin, LockedException lockedException
|
||||
) throws IOException, IncorrectPinException {
|
||||
var svr2Credentials = e.getSvr2Credentials();
|
||||
var svr2Credentials = lockedException.getSvr2Credentials();
|
||||
if (svr2Credentials != null) {
|
||||
return getRegistrationLockData(secureValueRecoveryV2, svr2Credentials, pin);
|
||||
IOException exception = null;
|
||||
for (final var secureValueRecovery : secureValueRecoveries) {
|
||||
try {
|
||||
return getRegistrationLockData(secureValueRecovery, svr2Credentials, pin);
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.whispersystems.signalservice.api.push.ServiceIdType;
|
|||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.DeprecatedVersionException;
|
||||
import org.whispersystems.signalservice.api.svr.SecureValueRecovery;
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
|
||||
import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
|
||||
|
||||
|
@ -90,7 +91,10 @@ public class RegistrationManagerImpl implements RegistrationManager {
|
|||
userAgent,
|
||||
groupsV2Operations,
|
||||
ServiceConfig.AUTOMATIC_NETWORK_RETRY);
|
||||
final var secureValueRecoveryV2 = accountManager.getSecureValueRecoveryV2(serviceEnvironmentConfig.svr2Mrenclave());
|
||||
final var secureValueRecoveryV2 = serviceEnvironmentConfig.svr2Mrenclaves()
|
||||
.stream()
|
||||
.map(mr -> (SecureValueRecovery) accountManager.getSecureValueRecoveryV2(mr))
|
||||
.toList();
|
||||
this.pinHelper = new PinHelper(secureValueRecoveryV2);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,14 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
|||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.services.ProfileService;
|
||||
import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV2;
|
||||
import org.whispersystems.signalservice.api.svr.SecureValueRecovery;
|
||||
import org.whispersystems.signalservice.api.util.CredentialsProvider;
|
||||
import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketFactory;
|
||||
import org.whispersystems.signalservice.internal.push.PushServiceSocket;
|
||||
import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -50,7 +51,7 @@ public class SignalDependencies {
|
|||
private SignalServiceMessageReceiver messageReceiver;
|
||||
private SignalServiceMessageSender messageSender;
|
||||
|
||||
private SecureValueRecoveryV2 secureValueRecoveryV2;
|
||||
private List<SecureValueRecovery> secureValueRecoveryV2;
|
||||
private ProfileService profileService;
|
||||
private SignalServiceCipher cipher;
|
||||
|
||||
|
@ -192,9 +193,12 @@ public class SignalDependencies {
|
|||
pushServiceSocket));
|
||||
}
|
||||
|
||||
public SecureValueRecoveryV2 getSecureValueRecoveryV2() {
|
||||
public List<SecureValueRecovery> getSecureValueRecoveryV2() {
|
||||
return getOrCreate(() -> secureValueRecoveryV2,
|
||||
() -> secureValueRecoveryV2 = getAccountManager().getSecureValueRecoveryV2(serviceEnvironmentConfig.svr2Mrenclave()));
|
||||
() -> secureValueRecoveryV2 = serviceEnvironmentConfig.svr2Mrenclaves()
|
||||
.stream()
|
||||
.map(mr -> (SecureValueRecovery) getAccountManager().getSecureValueRecoveryV2(mr))
|
||||
.toList());
|
||||
}
|
||||
|
||||
public ProfileService getProfileService() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue