OmemoConfiguration.java

  1. /**
  2.  *
  3.  * Copyright 2017 Paul Schaub
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.omemo;

  18. /**
  19.  * Contains OMEMO related configuration options.
  20.  *
  21.  * @author Paul Schaub
  22.  */
  23. public final class OmemoConfiguration {

  24.     private static boolean IGNORE_READ_ONLY_DEVICES = true;
  25.     private static int MAX_READ_ONLY_MESSAGE_COUNT = 400;

  26.     /**
  27.      * Set to true, in order to ignore read-only devices.
  28.      *
  29.      * @param ignore ignore read-only devices
  30.      * @see <a href="https://blog.jabberhead.tk/2019/12/13/pitfalls-for-omemo-implementations-part-1-inactive-devices/">Blog Post explaining the danger of read-only devices.</a>
  31.      */
  32.     public static void setIgnoreReadOnlyDevices(boolean ignore) {
  33.         IGNORE_READ_ONLY_DEVICES = ignore;
  34.     }

  35.     /**
  36.      * Return true, if the client should stop encrypting messages to a read-only device.
  37.      *
  38.      * @return true if read-only devices should get ignored after a certain amount of unanswered messages.
  39.      * @see <a href="https://blog.jabberhead.tk/2019/12/13/pitfalls-for-omemo-implementations-part-1-inactive-devices/">Blog Post explaining the danger of read-only devices.</a>
  40.      */
  41.     public static boolean getIgnoreReadOnlyDevices() {
  42.         return IGNORE_READ_ONLY_DEVICES;
  43.     }

  44.     /**
  45.      * Set the maximum amount of messages that the client is allowed to send to a read-only device without getting a
  46.      * response. Once the message counter of a device reaches that value, the client will stop encrypting messages for
  47.      * the device (given that {@link #getIgnoreReadOnlyDevices()} is true).
  48.      * This threshold is used to prevent read-only devices from weakening forward secrecy.
  49.      *
  50.      * @param maxReadOnlyMessageCount maximum number of allowed messages to a read-only device.
  51.      * @see <a href="https://blog.jabberhead.tk/2019/12/13/pitfalls-for-omemo-implementations-part-1-inactive-devices/">Blog Post explaining the danger of read-only devices.</a>
  52.      */
  53.     public static void setMaxReadOnlyMessageCount(int maxReadOnlyMessageCount) {
  54.         if (maxReadOnlyMessageCount <= 0) {
  55.             throw new IllegalArgumentException("maxReadOnlyMessageCount MUST be greater than 0.");
  56.         }
  57.         MAX_READ_ONLY_MESSAGE_COUNT = maxReadOnlyMessageCount;
  58.     }

  59.     /**
  60.      * Get the maximum amount of messages that the client is allowed to send to a read-only device without getting a
  61.      * response. Once the message counter of a device reaches that value, the client will stop encrypting messages for
  62.      * the device (given that {@link #getIgnoreReadOnlyDevices()} is true).
  63.      * This threshold is used to prevent read-only devices from weakening forward secrecy.
  64.      *
  65.      * @return maximum number of allowed messages to a read-only device.
  66.      * @see <a href="https://blog.jabberhead.tk/2019/12/13/pitfalls-for-omemo-implementations-part-1-inactive-devices/">Blog Post explaining the danger of read-only devices.</a>
  67.      */
  68.     public static int getMaxReadOnlyMessageCount() {
  69.         return MAX_READ_ONLY_MESSAGE_COUNT;
  70.     }

  71.     /**
  72.      * Delete stale devices from the device list after a period of time.
  73.      */
  74.     private static boolean DELETE_STALE_DEVICES = true;
  75.     private static int DELETE_STALE_DEVICE_AFTER_HOURS = 24 * 7 * 4;     //4 weeks

  76.     public static void setDeleteStaleDevices(boolean delete) {
  77.         DELETE_STALE_DEVICES = delete;
  78.     }

  79.     public static boolean getDeleteStaleDevices() {
  80.         return DELETE_STALE_DEVICES;
  81.     }

  82.     public static void setDeleteStaleDevicesAfterHours(int hours) {
  83.         if (hours <= 0) {
  84.             throw new IllegalArgumentException("Hours must be greater than 0.");
  85.         }
  86.         DELETE_STALE_DEVICE_AFTER_HOURS = hours;
  87.     }

  88.     public static int getDeleteStaleDevicesAfterHours() {
  89.         return DELETE_STALE_DEVICE_AFTER_HOURS;
  90.     }

  91.     /**
  92.      * Upload a new signed prekey in intervals. This improves forward secrecy. Old keys are kept for some more time and
  93.      * then deleted.
  94.      */
  95.     private static boolean RENEW_OLD_SIGNED_PREKEYS = false;
  96.     private static int RENEW_OLD_SIGNED_PREKEYS_AFTER_HOURS = 24 * 7;    //One week
  97.     private static int MAX_NUMBER_OF_STORED_SIGNED_PREKEYS = 4;

  98.     /**
  99.      * Decide, whether signed preKeys are automatically rotated or not.
  100.      * It is highly recommended to rotate signed preKeys to preserve forward secrecy.
  101.      *
  102.      * @param renew automatically rotate signed preKeys?
  103.      */
  104.     public static void setRenewOldSignedPreKeys(boolean renew) {
  105.         RENEW_OLD_SIGNED_PREKEYS = renew;
  106.     }

  107.     /**
  108.      * Determine, whether signed preKeys are automatically rotated or not.
  109.      *
  110.      * @return auto-rotate signed preKeys?
  111.      */
  112.     public static boolean getRenewOldSignedPreKeys() {
  113.         return RENEW_OLD_SIGNED_PREKEYS;
  114.     }

  115.     /**
  116.      * Set the interval in hours, after which the published signed preKey should be renewed.
  117.      * This value should be between one or two weeks.
  118.      *
  119.      * @param hours hours after which signed preKeys should be rotated.
  120.      */
  121.     public static void setRenewOldSignedPreKeysAfterHours(int hours) {
  122.         if (hours <= 0) {
  123.             throw new IllegalArgumentException("Hours must be greater than 0.");
  124.         }
  125.         RENEW_OLD_SIGNED_PREKEYS_AFTER_HOURS = hours;
  126.     }

  127.     /**
  128.      * Get the interval in hours, after which the published signed preKey should be renewed.
  129.      * This value should be between one or two weeks.
  130.      *
  131.      * @return hours after which signed preKeys should be rotated.
  132.      */
  133.     public static int getRenewOldSignedPreKeysAfterHours() {
  134.         return RENEW_OLD_SIGNED_PREKEYS_AFTER_HOURS;
  135.     }

  136.     /**
  137.      * Set the maximum number of signed preKeys that are cached until the oldest one gets deleted.
  138.      * This number should not be too small in order to prevent message loss, but also not too big
  139.      * to preserve forward secrecy.
  140.      *
  141.      * @param number number of cached signed preKeys.
  142.      */
  143.     public static void setMaxNumberOfStoredSignedPreKeys(int number) {
  144.         if (number <= 0) {
  145.             throw new IllegalArgumentException("Number must be greater than 0.");
  146.         }
  147.         MAX_NUMBER_OF_STORED_SIGNED_PREKEYS = number;
  148.     }

  149.     /**
  150.      * Return the maximum number of signed preKeys that are cached until the oldest one gets deleted.
  151.      * @return max number of cached signed preKeys.
  152.      */
  153.     public static int getMaxNumberOfStoredSignedPreKeys() {
  154.         return MAX_NUMBER_OF_STORED_SIGNED_PREKEYS;
  155.     }

  156.     /**
  157.      * Add a plaintext body hint about omemo encryption to the message.
  158.      */
  159.     private static boolean ADD_OMEMO_HINT_BODY = true;

  160.     /**
  161.      * Decide, whether an OMEMO message should carry a plaintext hint about OMEMO encryption.
  162.      * Eg. "I sent you an OMEMO encrypted message..."
  163.      *
  164.      * @param addHint shall we add a hint?
  165.      */
  166.     public static void setAddOmemoHintBody(boolean addHint) {
  167.         ADD_OMEMO_HINT_BODY = addHint;
  168.     }

  169.     /**
  170.      * Determine, whether an OMEMO message should carry a plaintext hint about OMEMO encryption.
  171.      *
  172.      * @return true, if a hint is added to the message.
  173.      */
  174.     public static boolean getAddOmemoHintBody() {
  175.         return ADD_OMEMO_HINT_BODY;
  176.     }

  177.     private static boolean REPAIR_BROKEN_SESSIONS_WITH_PREKEY_MESSAGES = true;

  178.     /**
  179.      * Determine, whether incoming messages, which have broken sessions should automatically be answered by an empty
  180.      * preKeyMessage in order to establish a new session.
  181.      *
  182.      * @return true if session should be repaired automatically.
  183.      */
  184.     public static boolean getRepairBrokenSessionsWithPreKeyMessages() {
  185.         return REPAIR_BROKEN_SESSIONS_WITH_PREKEY_MESSAGES;
  186.     }

  187.     /**
  188.      * Decide, whether incoming messages, which have broken sessions should automatically be answered by an empty
  189.      * preKeyMessage in order to establish a new session.
  190.      *
  191.      * @param repair repair sessions?
  192.      */
  193.     public static void setRepairBrokenSessionsWithPrekeyMessages(boolean repair) {
  194.         REPAIR_BROKEN_SESSIONS_WITH_PREKEY_MESSAGES = repair;
  195.     }

  196.     private static boolean COMPLETE_SESSION_WITH_EMPTY_MESSAGE = true;

  197.     /**
  198.      * Determine, whether incoming preKeyMessages should automatically be answered by an empty message in order to
  199.      * complete the session.
  200.      *
  201.      * @return true if sessions should be completed.
  202.      */
  203.     public static boolean getCompleteSessionWithEmptyMessage() {
  204.         return COMPLETE_SESSION_WITH_EMPTY_MESSAGE;
  205.     }

  206.     /**
  207.      * Decide, whether incoming preKeyMessages should automatically be answered by an empty message in order to
  208.      * complete the session.
  209.      *
  210.      * @param complete complete the session or not
  211.      */
  212.     public static void setCompleteSessionWithEmptyMessage(boolean complete) {
  213.         COMPLETE_SESSION_WITH_EMPTY_MESSAGE = complete;
  214.     }
  215. }