Search in sources :

Example 26 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class ProfileCipherTest method testEncryptLengthBucket2.

@Test
public void testEncryptLengthBucket2() throws InvalidInputException {
    ProfileKey key = new ProfileKey(Util.getSecretBytes(32));
    ProfileCipher cipher = new ProfileCipher(key);
    byte[] name = cipher.encrypt("Peter\0Parker".getBytes(), 257);
    String encoded = Base64.encodeBytes(name);
    assertEquals(380, encoded.length());
}
Also used : ProfileKey(org.signal.zkgroup.profiles.ProfileKey) Test(org.junit.Test)

Example 27 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class ProfileCipherTest method testStreamBadAuthentication.

@Test
public void testStreamBadAuthentication() throws Exception {
    assumeLibSignalSupportedOnOS();
    ProfileKey key = new ProfileKey(Util.getSecretBytes(32));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ProfileCipherOutputStream out = new ProfileCipherOutputStream(baos, key);
    out.write("This is an avatar".getBytes());
    out.flush();
    out.close();
    byte[] encrypted = baos.toByteArray();
    encrypted[encrypted.length - 1] ^= 1;
    try {
        readStream(encrypted, key, 2048);
        fail("failed to verify authenticate tag");
    } catch (IOException e) {
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) Test(org.junit.Test)

Example 28 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class DeviceActivity method onLink.

@SuppressLint("StaticFieldLeak")
@Override
public void onLink(final Uri uri) {
    new ProgressDialogAsyncTask<Void, Void, Integer>(this, R.string.DeviceProvisioningActivity_content_progress_title, R.string.DeviceProvisioningActivity_content_progress_content) {

        private static final int SUCCESS = 0;

        private static final int NO_DEVICE = 1;

        private static final int NETWORK_ERROR = 2;

        private static final int KEY_ERROR = 3;

        private static final int LIMIT_EXCEEDED = 4;

        private static final int BAD_CODE = 5;

        @Override
        protected Integer doInBackground(Void... params) {
            boolean isMultiDevice = TextSecurePreferences.isMultiDevice(DeviceActivity.this);
            try {
                Context context = DeviceActivity.this;
                SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
                String verificationCode = accountManager.getNewDeviceVerificationCode();
                String ephemeralId = uri.getQueryParameter("uuid");
                String publicKeyEncoded = uri.getQueryParameter("pub_key");
                if (TextUtils.isEmpty(ephemeralId) || TextUtils.isEmpty(publicKeyEncoded)) {
                    Log.w(TAG, "UUID or Key is empty!");
                    return BAD_CODE;
                }
                ECPublicKey publicKey = Curve.decodePoint(Base64.decode(publicKeyEncoded), 0);
                IdentityKeyPair aciIdentityKeyPair = SignalStore.account().getAciIdentityKey();
                IdentityKeyPair pniIdentityKeyPair = SignalStore.account().getPniIdentityKey();
                ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
                TextSecurePreferences.setMultiDevice(DeviceActivity.this, true);
                accountManager.addDevice(ephemeralId, publicKey, aciIdentityKeyPair, pniIdentityKeyPair, profileKey, verificationCode);
                return SUCCESS;
            } catch (NotFoundException e) {
                Log.w(TAG, e);
                TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
                return NO_DEVICE;
            } catch (DeviceLimitExceededException e) {
                Log.w(TAG, e);
                TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
                return LIMIT_EXCEEDED;
            } catch (IOException e) {
                Log.w(TAG, e);
                TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
                return NETWORK_ERROR;
            } catch (InvalidKeyException e) {
                Log.w(TAG, e);
                TextSecurePreferences.setMultiDevice(DeviceActivity.this, isMultiDevice);
                return KEY_ERROR;
            }
        }

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);
            Context context = DeviceActivity.this;
            switch(result) {
                case SUCCESS:
                    Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_success, Toast.LENGTH_SHORT).show();
                    finish();
                    return;
                case NO_DEVICE:
                    Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_no_device, Toast.LENGTH_LONG).show();
                    break;
                case NETWORK_ERROR:
                    Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_network_error, Toast.LENGTH_LONG).show();
                    break;
                case KEY_ERROR:
                    Toast.makeText(context, R.string.DeviceProvisioningActivity_content_progress_key_error, Toast.LENGTH_LONG).show();
                    break;
                case LIMIT_EXCEEDED:
                    Toast.makeText(context, R.string.DeviceProvisioningActivity_sorry_you_have_too_many_devices_linked_already, Toast.LENGTH_LONG).show();
                    break;
                case BAD_CODE:
                    Toast.makeText(context, R.string.DeviceActivity_sorry_this_is_not_a_valid_device_link_qr_code, Toast.LENGTH_LONG).show();
                    break;
            }
            getSupportFragmentManager().popBackStackImmediate();
        }
    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
Also used : Context(android.content.Context) SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) NotFoundException(org.whispersystems.signalservice.api.push.exceptions.NotFoundException) IOException(java.io.IOException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SuppressLint(android.annotation.SuppressLint) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) DeviceLimitExceededException(org.whispersystems.signalservice.internal.push.DeviceLimitExceededException) ECPublicKey(org.whispersystems.libsignal.ecc.ECPublicKey) IdentityKeyPair(org.whispersystems.libsignal.IdentityKeyPair) SuppressLint(android.annotation.SuppressLint)

Example 29 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class ProfileService method getProfile.

public Single<ServiceResponse<ProfileAndCredential>> getProfile(SignalServiceAddress address, Optional<ProfileKey> profileKey, Optional<UnidentifiedAccess> unidentifiedAccess, SignalServiceProfile.RequestType requestType, Locale locale) {
    ServiceId serviceId = address.getServiceId();
    SecureRandom random = new SecureRandom();
    ProfileKeyCredentialRequestContext requestContext = null;
    WebSocketProtos.WebSocketRequestMessage.Builder builder = WebSocketProtos.WebSocketRequestMessage.newBuilder().setId(random.nextLong()).setVerb("GET");
    if (profileKey.isPresent()) {
        ProfileKeyVersion profileKeyIdentifier = profileKey.get().getProfileKeyVersion(serviceId.uuid());
        String version = profileKeyIdentifier.serialize();
        if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) {
            requestContext = clientZkProfileOperations.createProfileKeyCredentialRequestContext(random, serviceId.uuid(), profileKey.get());
            ProfileKeyCredentialRequest request = requestContext.getRequest();
            String credentialRequest = Hex.toStringCondensed(request.serialize());
            builder.setPath(String.format("/v1/profile/%s/%s/%s", serviceId, version, credentialRequest));
        } else {
            builder.setPath(String.format("/v1/profile/%s/%s", serviceId, version));
        }
    } else {
        builder.setPath(String.format("/v1/profile/%s", address.getIdentifier()));
    }
    builder.addHeaders(AcceptLanguagesUtil.getAcceptLanguageHeader(locale));
    WebSocketProtos.WebSocketRequestMessage requestMessage = builder.build();
    ResponseMapper<ProfileAndCredential> responseMapper = DefaultResponseMapper.extend(ProfileAndCredential.class).withResponseMapper(new ProfileResponseMapper(requestType, requestContext)).build();
    return signalWebSocket.request(requestMessage, unidentifiedAccess).map(responseMapper::map).onErrorResumeNext(t -> restFallback(address, profileKey, unidentifiedAccess, requestType, locale)).onErrorReturn(ServiceResponse::forUnknownError);
}
Also used : Single(io.reactivex.rxjava3.core.Single) AcceptLanguagesUtil(org.whispersystems.signalservice.internal.push.http.AcceptLanguagesUtil) MalformedResponseException(org.whispersystems.signalservice.api.push.exceptions.MalformedResponseException) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) VerificationFailedException(org.signal.zkgroup.VerificationFailedException) SignalWebSocket(org.whispersystems.signalservice.api.SignalWebSocket) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) SecureRandom(java.security.SecureRandom) UnidentifiedAccess(org.whispersystems.signalservice.api.crypto.UnidentifiedAccess) Pair(org.whispersystems.libsignal.util.Pair) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) ProfileKeyCredentialRequest(org.signal.zkgroup.profiles.ProfileKeyCredentialRequest) Locale(java.util.Locale) Hex(org.whispersystems.signalservice.internal.util.Hex) DefaultResponseMapper(org.whispersystems.signalservice.internal.websocket.DefaultResponseMapper) ClientZkProfileOperations(org.signal.zkgroup.profiles.ClientZkProfileOperations) ProfileKeyCredential(org.signal.zkgroup.profiles.ProfileKeyCredential) ACI(org.whispersystems.signalservice.api.push.ACI) WebSocketProtos(org.whispersystems.signalservice.internal.websocket.WebSocketProtos) ProfileKeyVersion(org.signal.zkgroup.profiles.ProfileKeyVersion) Function(org.whispersystems.libsignal.util.guava.Function) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) JsonUtil(org.whispersystems.signalservice.internal.util.JsonUtil) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) ProfileKeyCredentialRequestContext(org.signal.zkgroup.profiles.ProfileKeyCredentialRequestContext) ResponseMapper(org.whispersystems.signalservice.internal.websocket.ResponseMapper) ServiceResponseProcessor(org.whispersystems.signalservice.internal.ServiceResponseProcessor) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) SecureRandom(java.security.SecureRandom) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) ProfileKeyCredentialRequestContext(org.signal.zkgroup.profiles.ProfileKeyCredentialRequestContext) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) ProfileKeyCredentialRequest(org.signal.zkgroup.profiles.ProfileKeyCredentialRequest) ProfileKeyVersion(org.signal.zkgroup.profiles.ProfileKeyVersion) WebSocketProtos(org.whispersystems.signalservice.internal.websocket.WebSocketProtos)

Example 30 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class RetrieveProfileJob method process.

private void process(Recipient recipient, ProfileAndCredential profileAndCredential) {
    SignalServiceProfile profile = profileAndCredential.getProfile();
    ProfileKey recipientProfileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey());
    setProfileName(recipient, profile.getName());
    setProfileAbout(recipient, profile.getAbout(), profile.getAboutEmoji());
    setProfileAvatar(recipient, profile.getAvatar());
    setProfileBadges(recipient, profile.getBadges());
    clearUsername(recipient);
    setProfileCapabilities(recipient, profile.getCapabilities());
    setUnidentifiedAccessMode(recipient, profile.getUnidentifiedAccess(), profile.isUnrestrictedUnidentifiedAccess());
    if (recipientProfileKey != null) {
        Optional<ProfileKeyCredential> profileKeyCredential = profileAndCredential.getProfileKeyCredential();
        if (profileKeyCredential.isPresent()) {
            setProfileKeyCredential(recipient, recipientProfileKey, profileKeyCredential.get());
        }
    }
}
Also used : ProfileKeyCredential(org.signal.zkgroup.profiles.ProfileKeyCredential) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile)

Aggregations

ProfileKey (org.signal.zkgroup.profiles.ProfileKey)150 Test (org.junit.Test)102 UUID (java.util.UUID)90 DecryptedGroup (org.signal.storageservice.protos.groups.local.DecryptedGroup)50 ProtoTestUtils.randomProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.randomProfileKey)50 DecryptedGroupChange (org.signal.storageservice.protos.groups.local.DecryptedGroupChange)34 ProtoTestUtils.newProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.newProfileKey)28 ProtoTestUtils.withProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withProfileKey)28 IOException (java.io.IOException)24 GroupChange (org.signal.storageservice.protos.groups.GroupChange)14 DecryptedMember (org.signal.storageservice.protos.groups.local.DecryptedMember)14 InvalidCiphertextException (org.whispersystems.signalservice.api.crypto.InvalidCiphertextException)12 InvalidInputException (org.signal.zkgroup.InvalidInputException)8 ProfileKeyCredential (org.signal.zkgroup.profiles.ProfileKeyCredential)8 Recipient (org.thoughtcrime.securesms.recipients.Recipient)8 InvalidKeyException (org.whispersystems.libsignal.InvalidKeyException)8 NonNull (androidx.annotation.NonNull)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)6 IdentityKey (org.whispersystems.libsignal.IdentityKey)6