java.lang.Object
net.i2p.router.crypto.ratchet.RatchetSKM.OutboundSession
Enclosing class:
RatchetSKM

class RatchetSKM.OutboundSessionextends Object
The state for a crypto session to a single public key.
  • Field Details

    • _target

      private final PublicKey _target
      The peer's ratchet public key.
    • _state

      private final HandshakeState _state
      Current state of the handshake.
    • _NScallback

      private ReplyCallback _NScallback
      Callback for an NS reply.
    • _NSRcallback

      private ReplyCallback _NSRcallback
      Callback for an NSR reply.
    • _currentKey

      private SessionKey _currentKey
      Key used for the most recent messages.
    • _established

      private final long _established
      When the session was created.
    • _lastUsed

      private long _lastUsed
      When we last sent through the session.
    • _lastReceived

      private long _lastReceived
      When we last received through the session.
    • _unackedTagSets

      private final Set<RatchetTagSet> _unackedTagSets
      Before the first ack, all tagsets go here. These are dropped by clear() when the session's tag state is reset or the session dies; a failsafe expire also removes stale sets. Unsynchronized, sync to use. No particular order.
    • _tagSet

      private RatchetTagSet _tagSet
      There is only one active outbound tagset. Synch on _unackedTagSets to access this.
    • _callbacks

      private final ConcurrentHashMap<Integer, ReplyCallback> _callbacks
      Reply callbacks by tag id.
    • _acksToSend

      private final LinkedBlockingQueue<Integer> _acksToSend
      Acknowledgements waiting to be sent.
    • _ackTimer

      private SimpleTimer2.TimedEvent _ackTimer
      Timer that flushes the pending acks.
    • _destination

      private Destination _destination
      The local destination owning the session.
    • _myOBKeyID

      private int _myOBKeyID
      Key id for our next outbound ratchet key.
    • _myIBKeyID

      private int _myIBKeyID
      Key id for our next inbound ratchet key.
    • _myIBKeySendCount

      private int _myIBKeySendCount
      Messages sent under our current inbound key.
    • _myIBKeys

      private KeyPair _myIBKeys
      Our current inbound ratchet key pair.
    • _myOBKeys

      private KeyPair _myOBKeys
      Our current outbound ratchet key pair.
    • _myIBKey

      private NextSessionKey _myIBKey
      Our next inbound key, sent ahead of use.
    • _hisIBKey

      private NextSessionKey _hisIBKey
      The last key received from the peer, possibly without data, for the duplicate check.
    • _hisOBKey

      private NextSessionKey _hisOBKey
      Their latest outbound key, possibly without data.
    • _hisIBKeyWithData

      private NextSessionKey _hisIBKeyWithData
      The last key received from the peer that carried data.
    • _hisOBKeyWithData

      private NextSessionKey _hisOBKeyWithData
      Their latest outbound key that carried data.
    • _nextIBRootKey

      private SessionKey _nextIBRootKey
      Root key for the next inbound receive chain.
    • MIN_RCV_WINDOW_NSR

      private static final int MIN_RCV_WINDOW_NSR
      Smallest NSR receive window, in keys.
      See Also:
    • MAX_RCV_WINDOW_NSR

      private static final int MAX_RCV_WINDOW_NSR
      Largest NSR receive window, in keys.
      See Also:
    • MIN_RCV_WINDOW_ES

      private static final int MIN_RCV_WINDOW_ES
      Smallest ES receive window, in keys.
      See Also:
    • MAX_RCV_WINDOW_ES

      private static final int MAX_RCV_WINDOW_ES
      Largest ES receive window, in keys.
      See Also:
    • INFO_0

      private static final String INFO_0
      HKDF info string for the reply tags.
      See Also:
    • INFO_7

      private static final String INFO_7
      HKDF info string for the ratchet tag set.
      See Also:
    • MAX_SEND_ACKS

      private static final int MAX_SEND_ACKS
      Most acknowledgements sent in one message.
      See Also:
    • MAX_SEND_REVERSE_KEY

      private static final int MAX_SEND_REVERSE_KEY
      Most reverse keys sent in one message.
      See Also:
  • Constructor Details

    • OutboundSession

      public OutboundSession(PublicKey target, Destination d, SessionKey key, HandshakeState state, ReplyCallback callback)
      Outbound session for the given target.
      Parameters:
      target - the far-end public key this session talks to
      d - may be null
      key - may be null
      state - the completed handshake state, source of the chaining key and the role that decides the tagset direction
      callback - may be null. Always null for IB.
  • Method Details

    • updateSession

      void updateSession(HandshakeState state, ReplyCallback callback, SplitKeys split)
      Inbound or outbound. Checks state.getRole() to determine. For outbound (NSR rcvd by Alice), sets session to transition to ES mode outbound. For inbound (NSR sent by Bob), sets up inbound ES tagset.
      Parameters:
      state - the handshake state to advance, whose role decides the direction
      callback - only for inbound (NSR sent by Bob), may be null
      split - the NSR split keys - new root chaining key ck plus the per-direction session keys k_ab and k_ba
    • nextKeyReceived

      public void nextKeyReceived(NextSessionKey key)
      Process a Next Session Key message, validating the ID sequence before advancing the ratchet to the new tag set key.
      Parameters:
      key - the received next-session-key message
    • getReverseSendKey

      private NextSessionKey getReverseSendKey()
      Reverse key to send, or null.
      Returns:
      the reverse send key
    • tagConsumed

      void tagConsumed(RatchetTagSet set)
      A tag was received for this inbound (ES) tagset.
      Parameters:
      set - the inbound tagset
    • firstTagConsumed

      void firstTagConsumed(RatchetTagSet set)
      First tag was received for this inbound (ES) tagset. Find the corresponding outbound (ES) tagset in _unackedTagSets, move it to _tagSets, and remove all others from _unackedTagSets.

      Note: We do NOT remove remaining inbound tags from _inboundTagSets here. The addTags() sliding window in consume() already handles tag lifecycle — generating new tags ahead and trimming old ones via RatchetSKM.expireTag(RatchetSessionTag, RatchetTagSet). Purging all tags on first consumption broke subsequent ES decryptions because Alice's retransmitted SYNs (using pre-generated tags 1-N) could no longer be found in _inboundTagSets.

      Parameters:
      set - the inbound tagset
    • getTagSets

      List<RatchetTagSet> getTagSets()
      This is used only by renderStatusHTML(). It includes both acked and unacked RatchetTagSets.
      Returns:
      list of RatchetTagSet objects
    • getTarget

      public PublicKey getTarget()
      The far-end public key this session talks to.
      Returns:
      the target key, set at construction
    • getHandshakeState

      public HandshakeState getHandshakeState()
      Original outbound state, null for inbound.
      Returns:
      the handshake state
    • getCurrentKey

      public SessionKey getCurrentKey()
      The session key stored at construction; never updated afterwards.
      Returns:
      the key, or null if the session was created without one
    • getEstablishedDate

      public long getEstablishedDate()
      When this session was established.
      Returns:
      creation time in ms
    • getLastUsedDate

      public long getLastUsedDate()
      NOT updated for inbound except for NSR and first ES tag used.
      Returns:
      the last used date
    • getLastReceivedDate

      public long getLastReceivedDate()
      ONLY updated for inbound NS/NSR/ES tag used.
      Returns:
      the last received date
    • expireTags

      public int expireTags(long now)
      Expire old tags, returning the number of tag sets removed.
      Parameters:
      now - current time in ms, tag sets expiring at or before it are removed
      Returns:
      the number of tag sets removed
    • consumeNext

      public RatchetEntry consumeNext()
      Consume the next available tag and advance.
      Returns:
      the next tag with its key, rotation keys and pending acks, or null if the session or tag set has expired or drained
    • registerTimer

      public boolean registerTimer(Destination d, SimpleTimer2.TimedEvent timer)
      A timer that we will cancel when we send something. Side effect - binds this session to the supplied destination.
      Parameters:
      d - the far-end Destination for this PublicKey if known, or null
      timer - the ack timer to hold, cancelled when this session sends; ignored if a timer is already registered
      Returns:
      true if registered
    • getDestination

      public Destination getDestination()
      Destination for the current session's far end.
      Returns:
      the far-end Destination for this PublicKey, or null
    • availableTags

      public int availableTags()
      Number of tags remaining in acked tag sets.
      Returns:
      the total number of tags in acked RatchetTagSets
    • getLastExpirationDate

      public long getLastExpirationDate()
      Furthest away tag set expiration date, after which all of the tags will have expired.
      Returns:
      the last expiration date
    • registerCallback

      public void registerCallback(int id, int n, ReplyCallback callback)
      Register the callback to run when the ACK for one ratchet tag arrives; a live callback for the same tag is not replaced.
      Parameters:
      id - tag set ID the ACK is for
      n - tag index within the tag set
      callback - callback to run on ACK
    • receivedACK

      public void receivedACK(int id, int n)
      Run and remove the callback registered for the ACKed tag, if any.
      Parameters:
      id - tag set ID the ACK is for
      n - tag index within the tag set
    • ackRequested

      public void ackRequested(int id, int n)
      Queue the ACK for one ratchet tag to be sent back.
      Parameters:
      id - tag set ID being ACKed
      n - tag index within the tag set
    • getAcksToSend

      private List<Integer> getAcksToSend()
      Pending acks drained from the queue, up to the send limit.
      Returns:
      the acks to send, non empty, or null
    • expireCallbacks

      public int expireCallbacks(long now)
      Drop reply callbacks whose expiration has passed.
      Parameters:
      now - current time in ms
      Returns:
      the number of callbacks removed