Search in sources :

Example 1 with SignatureVerification

use of com.nextcloud.talk.models.SignatureVerification in project talk-android by nextcloud.

the class PushUtils method verifySignature.

public SignatureVerification verifySignature(byte[] signatureBytes, byte[] subjectBytes) {
    Signature signature = null;
    PushConfigurationState pushConfigurationState;
    PublicKey publicKey;
    SignatureVerification signatureVerification = new SignatureVerification();
    signatureVerification.setSignatureValid(false);
    List<UserEntity> userEntities = userUtils.getUsers();
    try {
        signature = Signature.getInstance("SHA512withRSA");
        if (userEntities != null && userEntities.size() > 0) {
            for (UserEntity userEntity : userEntities) {
                if (!TextUtils.isEmpty(userEntity.getPushConfigurationState())) {
                    pushConfigurationState = LoganSquare.parse(userEntity.getPushConfigurationState(), PushConfigurationState.class);
                    publicKey = (PublicKey) readKeyFromString(true, pushConfigurationState.getUserPublicKey());
                    signature.initVerify(publicKey);
                    signature.update(subjectBytes);
                    if (signature.verify(signatureBytes)) {
                        signatureVerification.setSignatureValid(true);
                        signatureVerification.setUserEntity(userEntity);
                        return signatureVerification;
                    }
                }
            }
        }
    } catch (NoSuchAlgorithmException e) {
        Log.d(TAG, "No such algorithm");
    } catch (IOException e) {
        Log.d(TAG, "Error while trying to parse push configuration state");
    } catch (InvalidKeyException e) {
        Log.d(TAG, "Invalid key while trying to verify");
    } catch (SignatureException e) {
        Log.d(TAG, "Signature exception while trying to verify");
    }
    return signatureVerification;
}
Also used : PushConfigurationState(com.nextcloud.talk.models.json.push.PushConfigurationState) PublicKey(java.security.PublicKey) Signature(java.security.Signature) SignatureVerification(com.nextcloud.talk.models.SignatureVerification) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) IOException(java.io.IOException) SignatureException(java.security.SignatureException) InvalidKeyException(java.security.InvalidKeyException) UserEntity(com.nextcloud.talk.models.database.UserEntity)

Example 2 with SignatureVerification

use of com.nextcloud.talk.models.SignatureVerification in project talk-android by nextcloud.

the class NotificationJob method onRunJob.

@NonNull
@Override
protected Result onRunJob(Params params) {
    Context context = getContext();
    PersistableBundleCompat persistableBundleCompat = getParams().getExtras();
    String subject = persistableBundleCompat.getString(BundleKeys.KEY_NOTIFICATION_SUBJECT, "");
    String signature = persistableBundleCompat.getString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, "");
    if (!TextUtils.isEmpty(subject) && !TextUtils.isEmpty(signature)) {
        try {
            byte[] base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT);
            byte[] base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT);
            PushUtils pushUtils = new PushUtils();
            PrivateKey privateKey = (PrivateKey) pushUtils.readKeyFromFile(false);
            try {
                SignatureVerification signatureVerification = pushUtils.verifySignature(base64DecodedSignature, base64DecodedSubject);
                if (signatureVerification.isSignatureValid()) {
                    Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding");
                    cipher.init(Cipher.DECRYPT_MODE, privateKey);
                    byte[] decryptedSubject = cipher.doFinal(base64DecodedSubject);
                    DecryptedPushMessage decryptedPushMessage = LoganSquare.parse(new String(decryptedSubject), DecryptedPushMessage.class);
                    if (decryptedPushMessage.getApp().equals("spreed")) {
                        int smallIcon;
                        Bitmap largeIcon;
                        String category = "";
                        int priority = Notification.PRIORITY_DEFAULT;
                        Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                        Intent intent = new Intent(context, CallActivity.class);
                        Bundle bundle = new Bundle();
                        bundle.putString(BundleKeys.KEY_ROOM_TOKEN, decryptedPushMessage.getId());
                        bundle.putParcelable(BundleKeys.KEY_USER_ENTITY, Parcels.wrap(signatureVerification.getUserEntity()));
                        bundle.putBoolean("fromNotification", true);
                        intent.putExtras(bundle);
                        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                        switch(decryptedPushMessage.getType()) {
                            case "call":
                                smallIcon = R.drawable.ic_call_black_24dp;
                                category = Notification.CATEGORY_CALL;
                                priority = Notification.PRIORITY_HIGH;
                                soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
                                break;
                            case "room":
                                smallIcon = R.drawable.ic_notifications_black_24dp;
                                category = Notification.CATEGORY_CALL;
                                priority = Notification.PRIORITY_HIGH;
                                break;
                            case "chat":
                                smallIcon = R.drawable.ic_chat_black_24dp;
                                category = Notification.CATEGORY_MESSAGE;
                                break;
                            default:
                                smallIcon = R.drawable.ic_logo;
                        }
                        largeIcon = BitmapFactory.decodeResource(context.getResources(), smallIcon);
                        CRC32 crc32 = new CRC32();
                        Notification.Builder notificationBuilder = new Notification.Builder(context).setLargeIcon(largeIcon).setSmallIcon(smallIcon).setCategory(category).setPriority(priority).setWhen(Calendar.getInstance().getTimeInMillis()).setShowWhen(true).setSubText(signatureVerification.getUserEntity().getDisplayName()).setContentTitle(decryptedPushMessage.getSubject()).setSound(soundUri).setAutoCancel(true);
                        if (Build.VERSION.SDK_INT >= 23) {
                            // This method should exist since API 21, but some phones don't have it
                            // So as a safeguard, we don't use it until 23
                            notificationBuilder.setColor(context.getResources().getColor(R.color.colorPrimary));
                        }
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            String groupName = String.format(context.getResources().getString(R.string.nc_notification_channel), signatureVerification.getUserEntity().getDisplayName(), signatureVerification.getUserEntity().getBaseUrl());
                            crc32.update(groupName.getBytes());
                            NotificationUtils.createNotificationChannelGroup(notificationManager, Long.toString(crc32.getValue()), groupName);
                            if (category.equals(Notification.CATEGORY_CALL)) {
                                NotificationUtils.createNotificationChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_CALLS, context.getResources().getString(R.string.nc_notification_channel_calls), context.getResources().getString(R.string.nc_notification_channel_calls_description), true, NotificationManager.IMPORTANCE_HIGH, soundUri);
                                notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_CALLS);
                            } else {
                                NotificationUtils.createNotificationChannel(notificationManager, NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES, context.getResources().getString(R.string.nc_notification_channel_messages), context.getResources().getString(R.string.nc_notification_channel_messages_description), true, NotificationManager.IMPORTANCE_DEFAULT, soundUri);
                                notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES);
                            }
                            notificationBuilder.setGroup(Long.toString(crc32.getValue()));
                        }
                        notificationBuilder.setContentIntent(pendingIntent);
                        String stringForCrc = decryptedPushMessage.getSubject() + " " + signatureVerification.getUserEntity().getDisplayName() + " " + signatureVerification.getUserEntity().getBaseUrl();
                        crc32 = new CRC32();
                        crc32.update(stringForCrc.getBytes());
                        if (notificationManager != null) {
                            notificationManager.notify((int) crc32.getValue(), notificationBuilder.build());
                        }
                    }
                }
            } catch (NoSuchAlgorithmException e1) {
                Log.d(TAG, "No proper algorithm to decrypt the message " + e1.getLocalizedMessage());
            } catch (NoSuchPaddingException e1) {
                Log.d(TAG, "No proper padding to decrypt the message " + e1.getLocalizedMessage());
            } catch (InvalidKeyException e1) {
                Log.d(TAG, "Invalid private key " + e1.getLocalizedMessage());
            }
        } catch (Exception exception) {
            Log.d(TAG, "Something went very wrong" + exception.getLocalizedMessage());
        }
    }
    return Result.SUCCESS;
}
Also used : Context(android.content.Context) PersistableBundleCompat(com.evernote.android.job.util.support.PersistableBundleCompat) PushUtils(com.nextcloud.talk.utils.PushUtils) PrivateKey(java.security.PrivateKey) NotificationManager(android.app.NotificationManager) CRC32(java.util.zip.CRC32) Bundle(android.os.Bundle) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) SignatureVerification(com.nextcloud.talk.models.SignatureVerification) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) Uri(android.net.Uri) Notification(android.app.Notification) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) DecryptedPushMessage(com.nextcloud.talk.models.json.push.DecryptedPushMessage) Bitmap(android.graphics.Bitmap) Cipher(javax.crypto.Cipher) PendingIntent(android.app.PendingIntent) NonNull(android.support.annotation.NonNull)

Aggregations

SignatureVerification (com.nextcloud.talk.models.SignatureVerification)2 InvalidKeyException (java.security.InvalidKeyException)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 Notification (android.app.Notification)1 NotificationManager (android.app.NotificationManager)1 PendingIntent (android.app.PendingIntent)1 Context (android.content.Context)1 Intent (android.content.Intent)1 Bitmap (android.graphics.Bitmap)1 Uri (android.net.Uri)1 Bundle (android.os.Bundle)1 NonNull (android.support.annotation.NonNull)1 PersistableBundleCompat (com.evernote.android.job.util.support.PersistableBundleCompat)1 UserEntity (com.nextcloud.talk.models.database.UserEntity)1 DecryptedPushMessage (com.nextcloud.talk.models.json.push.DecryptedPushMessage)1 PushConfigurationState (com.nextcloud.talk.models.json.push.PushConfigurationState)1 PushUtils (com.nextcloud.talk.utils.PushUtils)1 IOException (java.io.IOException)1 PrivateKey (java.security.PrivateKey)1 PublicKey (java.security.PublicKey)1