java.lang.Object
net.i2p.router.message.GarlicMessageBuilder

public class GarlicMessageBuilderextends Object
Static methods to build GarlicMessages from a GarlicConfig, for both ElGamal/AES and ECIES (X25519 + PQ) encryption schemes.

All methods are stateless and thread-safe.

  • Constructor Details

    • GarlicMessageBuilder

      private GarlicMessageBuilder()
      Utility class, not intended for instantiation.
  • Method Details

    • needsTags

      static boolean needsTags(RouterContext ctx, PublicKey key, Hash local, int minTagOverride)
      ELGAMAL_2048 only; returns false for others.
      Parameters:
      ctx - the RouterContext supplying the log and session key manager
      key - the ElGamal 2048 recipient key the tags are decided for
      local - non-null; do not use this method for the router's SessionKeyManager
      minTagOverride - 0 for no override, > 0 to override SKM's settings
      Returns:
      true if the current session key should be accompanied by tags
    • buildMessage

      public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, SessionKeyManager skm)
      ELGAMAL_2048 only.
      Parameters:
      ctx - the RouterContext supplying the log and ElGamal/AES engine
      config - how/what to wrap
      wrappedKey - non-null with null data, output parameter that will be filled with the SessionKey used
      wrappedTags - Output parameter that will be filled with the sessionTags used. If non-empty on return you must call skm.tagsDelivered() when sent and then call skm.tagsAcked() or skm.failTags() later.
      skm - non-null
      Returns:
      null if expired
      Throws:
      IllegalArgumentException - if the recipient is null or carries no public key, or is not ELGAMAL_2048
    • buildMessage

      public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, int numTagsToDeliver, SessionKeyManager skm)
      ELGAMAL_2048 only Called by OCMJH.
      Parameters:
      ctx - the RouterContext supplying the log and ElGamal/AES engine
      config - how/what to wrap
      wrappedKey - non-null with null data, output parameter that will be filled with the SessionKey used
      wrappedTags - Output parameter that will be filled with the sessionTags used. If non-empty on return you must call skm.tagsDelivered() when sent and then call skm.tagsAcked() or skm.failTags() later.
      numTagsToDeliver - Only if the estimated available tags are below the threshold. Set to zero to disable tag delivery. You must set to zero if you are not equipped to confirm delivery and call skm.tagsAcked() or skm.failTags() later.
      skm - non-null
      Returns:
      null if expired
      Throws:
      IllegalArgumentException - if the recipient is null or carries no public key, or is not ELGAMAL_2048
    • buildMessage

      public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, int numTagsToDeliver, int lowTagsThreshold, SessionKeyManager skm)
      ELGAMAL_2048 only. Called by netdb and above.
      Parameters:
      ctx - the RouterContext supplying the log and ElGamal/AES engine
      config - how/what to wrap
      wrappedKey - non-null with null data, output parameter that will be filled with the SessionKey used
      wrappedTags - Output parameter that will be filled with the sessionTags used. If non-empty on return you must call skm.tagsDelivered() when sent and then call skm.tagsAcked() or skm.failTags() later.
      numTagsToDeliver - only if the estimated available tags are below the threshold. Set to zero to disable tag delivery. You must set to zero if you are not equipped to confirm delivery and call skm.tagsAcked() or failTags() later. If this is always 0, it forces ElGamal every time.
      lowTagsThreshold - the available-tag count below which the session key manager considers tags low enough to send
      skm - non-null
      Returns:
      null if expired
      Throws:
      IllegalArgumentException - if the recipient is null or carries no public key, or is not ELGAMAL_2048
    • buildMessage

      public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, Set<SessionTag> wrappedTags, PublicKey target, SessionKey encryptKey, SessionTag encryptTag)
      ELGAMAL_2048 only. Used by TestJob, and directly above, and by MessageWrapper for encrypting DatabaseLookupMessages and DSM/DSRM replies.
      Parameters:
      ctx - the RouterContext supplying the log and ElGamal/AES engine
      config - how/what to wrap
      wrappedTags - New tags to be sent along with the message. 200 max enforced at receiver; null OK
      target - public key of the location being garlic routed to (may be null if we know the encryptKey and encryptTag)
      encryptKey - sessionKey used to encrypt the current message, non-null
      encryptTag - sessionTag used to encrypt the current message, null to force ElG
      Returns:
      null if expired
      Throws:
      IllegalArgumentException - if the config is null, or a clove in it is not a PayloadGarlicConfig
    • buildMessage

      public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey encryptKey, RatchetSessionTag encryptTag)
      Ratchet only. Used by TestJob, and by MessageWrapper for encrypting DatabaseLookupMessages and DSM/DSRM replies.
      Parameters:
      ctx - the RouterContext supplying the log and ElGamal/AES engine
      config - how/what to wrap
      encryptKey - sessionKey used to encrypt the current message, non-null
      encryptTag - sessionTag used to encrypt the current message, non-null
      Returns:
      the encrypted GarlicMessage, or null if the ECIES encrypt failed
    • buildECIESMessage

      static GarlicMessage buildECIESMessage(RouterContext ctx, GarlicConfig config, Hash from, Destination to, SessionKeyManager skm, ReplyCallback callback)
      ECIES_X25519 and PQ only. Called by OCMJH only.
      Parameters:
      ctx - the RouterContext supplying the log and ECIES engine
      config - how/what to wrap, must have key set with setRecipientPublicKey()
      from - the local destination whose LeaseSet keys supply the private key
      to - the remote destination the message is addressed to, whose keys select the ratchet session
      skm - the session key manager holding that ratchet session
      callback - may be null
      Returns:
      null if expired or on other errors
      Throws:
      IllegalArgumentException - if the recipient key type is outside the EC/PQ set
    • buildECIESMessage

      public static GarlicMessage buildECIESMessage(RouterContext ctx, GarlicConfig config)
      Encrypt from an anonymous source. ECIES_X25519 only. PQ not supported. Called by MessageWrapper only.
      Parameters:
      ctx - the RouterContext supplying the log and ECIES engine
      config - how/what to wrap, must have key set with setRecipientPublicKey()
      Returns:
      the encrypted GarlicMessage, or null if the ECIES encrypt failed
      Throws:
      IllegalArgumentException - if the recipient key type is outside the EC/PQ set
    • buildCloveSet

      private static byte[] buildCloveSet(RouterContext ctx, GarlicConfig config)
      Build the unencrypted GarlicMessage specified by the config. It contains the number of cloves, followed by each clove, followed by a certificate, ID, and expiration date.
      Parameters:
      ctx - the router context for the clove builder
      config - single payload config, or a multi-clove config
      Returns:
      the unencrypted clove set bytes, ready to encrypt
      Throws:
      IllegalArgumentException - if a clove is not a PayloadGarlicConfig, or the clove set cannot be serialized
    • buildClove

      private static byte[] buildClove(RouterContext ctx, PayloadGarlicConfig config)
      Builds one clove's encrypted payload.
      Parameters:
      ctx - the router context
      config - what to include in the clove
      Returns:
      the clove's data
    • buildCommonClove

      private static byte[] buildCommonClove(GarlicClove clove, GarlicConfig config)
      Builds the part of a clove common to all types.
      Parameters:
      clove - the clove to build
      config - what to include
      Returns:
      the clove's data
    • buildECIESCloveSet

      private static CloveSet buildECIESCloveSet(RouterContext ctx, GarlicConfig config)
      Build the unencrypted CloveSet specified by the config. Unlike for Elgamal, the cloves do not contain a unique ID and expiration, and the CloveSet does not contain a unique certificate, ID, or expiration date.
      Parameters:
      ctx - the router context for the clove builder
      config - single payload config, or a multi-clove config
      Returns:
      a CloveSet of the built cloves with a null certificate
      Throws:
      IllegalArgumentException - if a clove is not a PayloadGarlicConfig
    • buildECIESClove

      private static GarlicClove buildECIESClove(RouterContext ctx, PayloadGarlicConfig config)
      Build a single clove.
      Parameters:
      ctx - the router context for the clove
      config - the payload config supplying data, expiration and instructions
      Returns:
      an unencrypted clove with a null certificate and clove ID 0