Search in sources :

Example 16 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class CdshService method getRegisteredUsers.

public Single<ServiceResponse<Map<String, ACI>>> getRegisteredUsers(String username, String password, Set<String> e164Numbers) {
    return Single.create(emitter -> {
        AtomicReference<Stage> stage = new AtomicReference<>(Stage.WAITING_TO_INITIALIZE);
        List<String> addressBook = e164Numbers.stream().map(e -> e.substring(1)).collect(Collectors.toList());
        String url = String.format("%s/discovery/%s/%s", baseUrl, hexPublicKey, hexCodeHash);
        Request request = new Request.Builder().url(url).build();
        WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() {

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                switch(stage.get()) {
                    case WAITING_TO_INITIALIZE:
                        enclave.completeHandshake(bytes.toByteArray());
                        byte[] request = enclave.establishedSend(buildPlaintextRequest(username, password, addressBook));
                        stage.set(Stage.WAITING_FOR_RESPONSE);
                        webSocket.send(ByteString.of(request));
                        break;
                    case WAITING_FOR_RESPONSE:
                        byte[] response = enclave.establishedRecv(bytes.toByteArray());
                        try {
                            Map<String, ACI> out = parseResponse(addressBook, response);
                            emitter.onSuccess(ServiceResponse.forResult(out, 200, null));
                        } catch (IOException e) {
                            emitter.onSuccess(ServiceResponse.forUnknownError(e));
                        } finally {
                            webSocket.close(1000, "OK");
                        }
                        break;
                    case FAILURE:
                        Log.w(TAG, "Received a message after we entered the failure state! Ignoring.");
                        webSocket.close(1000, "OK");
                        break;
                }
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                if (code != 1000) {
                    Log.w(TAG, "Remote side is closing with non-normal code " + code);
                    webSocket.close(1000, "Remote closed with code " + code);
                    stage.set(Stage.FAILURE);
                    emitter.onSuccess(ServiceResponse.forApplicationError(new NonSuccessfulResponseCodeException(code), code, null));
                }
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                emitter.onSuccess(ServiceResponse.forApplicationError(t, response != null ? response.code() : 0, null));
                stage.set(Stage.FAILURE);
                webSocket.close(1000, "OK");
            }
        });
        webSocket.send(ByteString.of(enclave.initialRequest()));
        emitter.setCancellable(() -> webSocket.close(1000, "OK"));
    });
}
Also used : DataInputStream(java.io.DataInputStream) SSLContext(javax.net.ssl.SSLContext) Single(io.reactivex.rxjava3.core.Single) ByteArrayOutputStream(java.io.ByteArrayOutputStream) HsmEnclaveClient(org.signal.libsignal.hsmenclave.HsmEnclaveClient) Util(org.whispersystems.signalservice.internal.util.Util) TrustManager(javax.net.ssl.TrustManager) HashMap(java.util.HashMap) WebSocketListener(okhttp3.WebSocketListener) TrustStore(org.whispersystems.signalservice.api.push.TrustStore) AtomicReference(java.util.concurrent.atomic.AtomicReference) Tls12SocketFactory(org.whispersystems.signalservice.api.util.Tls12SocketFactory) Pair(org.whispersystems.libsignal.util.Pair) ByteArrayInputStream(java.io.ByteArrayInputStream) NonSuccessfulResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException) Map(java.util.Map) ByteString(okio.ByteString) ConnectionSpec(okhttp3.ConnectionSpec) Response(okhttp3.Response) Log(org.whispersystems.libsignal.logging.Log) Hex(org.whispersystems.signalservice.internal.util.Hex) Request(okhttp3.Request) ACI(org.whispersystems.signalservice.api.push.ACI) Set(java.util.Set) IOException(java.io.IOException) WebSocket(okhttp3.WebSocket) KeyManagementException(java.security.KeyManagementException) UUID(java.util.UUID) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) SignalServiceConfiguration(org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration) ByteUtil(org.whispersystems.libsignal.util.ByteUtil) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) OkHttpClient(okhttp3.OkHttpClient) X509TrustManager(javax.net.ssl.X509TrustManager) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BlacklistingTrustManager(org.whispersystems.signalservice.internal.util.BlacklistingTrustManager) Collections(java.util.Collections) WebSocketListener(okhttp3.WebSocketListener) ByteString(okio.ByteString) Request(okhttp3.Request) NonSuccessfulResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException) AtomicReference(java.util.concurrent.atomic.AtomicReference) ByteString(okio.ByteString) IOException(java.io.IOException) WebSocket(okhttp3.WebSocket) Response(okhttp3.Response) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) HashMap(java.util.HashMap) Map(java.util.Map)

Example 17 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class LiveRecipientCache method getSelf.

@NonNull
Recipient getSelf() {
    RecipientId selfId;
    synchronized (localRecipientId) {
        selfId = localRecipientId.get();
    }
    if (selfId == null) {
        ACI localAci = SignalStore.account().getAci();
        String localE164 = SignalStore.account().getE164();
        if (localAci == null && localE164 == null) {
            throw new IllegalStateException("Tried to call getSelf() before local data was set!");
        }
        if (localAci != null) {
            selfId = recipientDatabase.getByServiceId(localAci).orNull();
        }
        if (selfId == null && localE164 != null) {
            selfId = recipientDatabase.getByE164(localE164).orNull();
        }
        if (selfId == null) {
            selfId = recipientDatabase.getAndPossiblyMerge(localAci, localE164, true);
        }
        synchronized (localRecipientId) {
            if (localRecipientId.get() == null) {
                localRecipientId.set(selfId);
            }
        }
    }
    return getLive(selfId).resolve();
}
Also used : ACI(org.whispersystems.signalservice.api.push.ACI) NonNull(androidx.annotation.NonNull)

Example 18 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class Recipient method external.

/**
 * Returns a fully-populated {@link Recipient} based off of a string identifier, creating one in
 * the database if necessary. The identifier may be a uuid, phone number, email,
 * or serialized groupId.
 *
 * If the identifier is a UUID of a Signal user, prefer using
 * {@link #externalPush(ServiceId, String, boolean)} or its overload, as this will let us associate
 * the phone number with the recipient.
 */
@WorkerThread
@NonNull
public static Recipient external(@NonNull Context context, @NonNull String identifier) {
    Preconditions.checkNotNull(identifier, "Identifier cannot be null!");
    RecipientDatabase db = SignalDatabase.recipients();
    RecipientId id = null;
    if (UuidUtil.isUuid(identifier)) {
        ACI uuid = ACI.parseOrThrow(identifier);
        id = db.getOrInsertFromServiceId(uuid);
    } else if (GroupId.isEncodedGroup(identifier)) {
        id = db.getOrInsertFromGroupId(GroupId.parseOrThrow(identifier));
    } else if (NumberUtil.isValidEmail(identifier)) {
        id = db.getOrInsertFromEmail(identifier);
    } else {
        String e164 = PhoneNumberFormatter.get(context).format(identifier);
        id = db.getOrInsertFromE164(e164);
    }
    return Recipient.resolved(id);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) ACI(org.whispersystems.signalservice.api.push.ACI) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 19 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class ContactDiscoveryV2 method getDirectoryResult.

@WorkerThread
static DirectoryResult getDirectoryResult(@NonNull Context context, @NonNull Set<String> databaseNumbers, @NonNull Set<String> systemNumbers) throws IOException {
    Set<String> allNumbers = SetUtil.union(databaseNumbers, systemNumbers);
    FuzzyPhoneNumberHelper.InputResult inputResult = FuzzyPhoneNumberHelper.generateInput(allNumbers, databaseNumbers);
    Set<String> sanitizedNumbers = sanitizeNumbers(inputResult.getNumbers());
    Set<String> ignoredNumbers = new HashSet<>();
    if (sanitizedNumbers.size() > MAX_NUMBERS) {
        Set<String> randomlySelected = randomlySelect(sanitizedNumbers, MAX_NUMBERS);
        ignoredNumbers = SetUtil.difference(sanitizedNumbers, randomlySelected);
        sanitizedNumbers = randomlySelected;
    }
    SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
    KeyStore iasKeyStore = getIasKeyStore(context);
    try {
        Map<String, ACI> results = accountManager.getRegisteredUsers(iasKeyStore, sanitizedNumbers, BuildConfig.CDS_MRENCLAVE);
        FuzzyPhoneNumberHelper.OutputResult outputResult = FuzzyPhoneNumberHelper.generateOutput(results, inputResult);
        return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers);
    } catch (SignatureException | UnauthenticatedQuoteException | UnauthenticatedResponseException | Quote.InvalidQuoteFormatException | InvalidKeyException e) {
        Log.w(TAG, "Attestation error.", e);
        throw new IOException(e);
    }
}
Also used : SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) ACI(org.whispersystems.signalservice.api.push.ACI) SignatureException(java.security.SignatureException) IOException(java.io.IOException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) KeyStore(java.security.KeyStore) DirectoryResult(org.thoughtcrime.securesms.contacts.sync.DirectoryHelper.DirectoryResult) UnauthenticatedResponseException(org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException) HashSet(java.util.HashSet) UnauthenticatedQuoteException(org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException) WorkerThread(androidx.annotation.WorkerThread)

Example 20 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class UuidMigrationJob method fetchOwnUuid.

private static void fetchOwnUuid(@NonNull Context context) throws IOException {
    RecipientId self = Recipient.self().getId();
    ACI localUuid = ACI.parseOrNull(ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI().getAci());
    if (localUuid == null) {
        throw new IOException("Invalid UUID!");
    }
    SignalDatabase.recipients().markRegisteredOrThrow(self, localUuid);
    SignalStore.account().setAci(localUuid);
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ACI(org.whispersystems.signalservice.api.push.ACI) IOException(java.io.IOException)

Aggregations

ACI (org.whispersystems.signalservice.api.push.ACI)32 Test (org.junit.Test)13 IOException (java.io.IOException)7 WorkerThread (androidx.annotation.WorkerThread)6 HashMap (java.util.HashMap)5 NonNull (androidx.annotation.NonNull)4 ByteString (com.google.protobuf.ByteString)4 ByteArrayInputStream (java.io.ByteArrayInputStream)4 DataInputStream (java.io.DataInputStream)4 Map (java.util.Map)4 PNI (org.whispersystems.signalservice.api.push.PNI)4 ServiceResponse (org.whispersystems.signalservice.internal.ServiceResponse)4 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 SignatureException (java.security.SignatureException)3 Collections (java.util.Collections)3 HashSet (java.util.HashSet)3 List (java.util.List)3 UUID (java.util.UUID)3 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)3 UnauthenticatedResponseException (org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException)3