net.i2p.data

## Class LeaseSet

- java.lang.Object
- - net.i2p.data.DataStructureImpl
  - - net.i2p.data.DatabaseEntry
    - - net.i2p.data.LeaseSet

- All Implemented Interfaces:
    Serializable, DataStructure
  Direct Known Subclasses:
    LeaseSet2

      public class LeaseSet
      extends DatabaseEntry

  Defines the set of leases that a destination currently has available for routing messages.

  LeaseSet is the fundamental routing structure in I2P, containing:

  - Destination: The service endpoint identity
  - Encryption Key: Public key for encrypting messages to the destination
  - Signing Key: Public key for verifying LeaseSet authenticity
  - Leases: List of tunnel endpoints and their validity periods
  - Signature: Cryptographic signature proving authenticity

  Lease Structure:

  - Gateway: Router identity that hosts the tunnel endpoint
  - Tunnel ID: Unique identifier for the tunnel on the gateway
  - Expiration: Time when the lease becomes invalid

  Encryption Support (Legacy):

  - ⚠️ SECURITY WARNING: Encryption is poorly designed and probably insecure
  - Not Recommended: Use modern alternatives like EncryptedLeaseSet
  - Limited Scope: Only encrypts gateway and tunnel ID data
  - No Indication: Encrypted leases appear identical to unencrypted ones
  - Keyring Required: Routers need desthash and key to decrypt

  Encryption Process:

  - Client Side: Encryption performed in I2CP client
  - Router Side: Local router must decrypt for usage
  - Network: Encrypted form transmitted to floodfills
  - Access: Decrypted leases only available via `getLease(int)`

  Usage:

  - Routing: Primary mechanism for message delivery in I2P
  - Load Balancing: Multiple leases provide redundancy and distribution
  - Mobility: Leases can be updated as endpoints change
  - Discovery: Published to network database for lookup

  Security Considerations:

  - Signature Verification: Always verify LeaseSet signatures
  - Expiration Checking: Ensure leases are still valid
  - Encryption Avoidance: Legacy encryption should not be used
  - Modern Alternatives: Use LeaseSet2, EncryptedLeaseSet, or MetaLeaseSet

  Migration Path:

  - LeaseSet2: Enhanced format with better security and features
  - EncryptedLeaseSet: Proper encryption with authentication
  - MetaLeaseSet: Advanced routing and load balancing
  leases and the original leaseset signature. Revocation (zero leases) isn't used anywhere. In addition: - A revoked leaseset has an EarliestLeaseDate of -1, so it will never be stored successfully. - Revocation of an encrypted leaseset will explode. - So having an included signature at all is pointless?
  See Also:
    Serialized Form

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `protected byte[]` | `_byteified`
    `protected boolean` | `_checked`
    `protected Destination` | `_destination`
    `protected PublicKey` | `_encryptionKey`
    `protected long` | `_lastExpiration`
    `protected List<Lease>` | `_leases`
    `protected SigningPublicKey` | `_signingKey`
    `static int` | `MAX_LEASES` Unlimited before 0.6.3; 6 as of 0.6.3; Increased in version 0.9.

    - ### Fields inherited from class net.i2p.data.DatabaseEntry

      `_signature, KEY_TYPE_ENCRYPTED_LS2, KEY_TYPE_LEASESET, KEY_TYPE_LS2, KEY_TYPE_META_LS2, KEY_TYPE_ROUTERINFO, KEY_TYPE_SERVICE_LIST, KEY_TYPE_SERVICE_RECORD`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `LeaseSet()`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `addLease(Lease lease)` Adds a lease to this leaseset.
    `void` | `encrypt(SessionKey key)` Encrypt the gateway and tunnel ID of each lease, leaving the expire dates unchanged.
    `boolean` | `equals(Object object)`
    `protected byte[]` | `getBytes()` without sig!
    `long` | `getDate()` Same as getEarliestLeaseDate()
    `Destination` | `getDestination()` Warning - will be null for LS2 EncryptedLeaseSets if not decrypted
    `long` | `getEarliestLeaseDate()` Retrieve the end date of the earliest lease included in this leaseSet.
    `PublicKey` | `getEncryptionKey()`
    `PublicKey` | `getEncryptionKey(Set<EncType> supported)` If more than one key, return the first supported one.
    `KeysAndCert` | `getKeysAndCert()` Get the keys and the cert Identical to getDestination() in LeaseSet, and getIdentity() in RouterInfo.
    `long` | `getLatestLeaseDate()` Retrieve the end date of the latest lease included in this leaseSet.
    `Lease` | `getLease(int index)`
    `int` | `getLeaseCount()` Gets the number of leases in this leaseset.
    `SigningPublicKey` | `getSigningKey()` The revocation key.
    `int` | `getType()` Get the type of the data structure.
    `int` | `hashCode()` the destination has enough randomness in it to use it by itself for speed
    `boolean` | `isCurrent(long fudge)` Determine whether ANY lease is currently valid, at least within a given fudge factor
    `void` | `readBytes(InputStream in)` This does NOT validate the signature
    `void` | `setDestination(Destination dest)` Sets the destination for this leaseset.
    `void` | `setEncryptionKey(PublicKey encryptionKey)` Sets the encryption key for this leaseset.
    `void` | `setReceivedBy(Hash localClient)` As of 0.9.65, no longer sets receivedAsReply to true
    `void` | `setSigningKey(SigningPublicKey key)` The revocation key.
    `int` | `size()` Number of bytes, NOT including signature
    `String` | `toString()`
    `boolean` | `verifySignature()` Verify that the signature matches the leaseset's destination's signing public key.
    `void` | `writeBytes(OutputStream out)` This does NOT validate the signature

    - ### Methods inherited from class net.i2p.data.DatabaseEntry

      `getHash, getReceivedAsPublished, getReceivedAsReply, getReceivedBy, getRoutingKey, getSignature, getSigningPublicKey, isLeaseSet, isLeaseSet, isRouterInfo, setReceivedAsPublished, setReceivedAsReply, setSignature, sign, validateRoutingKey`

    - ### Methods inherited from class net.i2p.data.DataStructureImpl

      `calculateHash, fromBase64, fromByteArray, read, toBase64, toByteArray`

    - ### Methods inherited from class java.lang.Object

      `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### _byteified

          protected volatile byte[] _byteified

    - #### _checked

          protected boolean _checked

    - #### _destination

          protected Destination _destination

    - #### _encryptionKey

          protected PublicKey _encryptionKey

    - #### _lastExpiration

          protected long _lastExpiration

    - #### _leases

          protected final List<Lease> _leases

    - #### _signingKey

          protected SigningPublicKey _signingKey

    - #### MAX_LEASES

          public static final int MAX_LEASES

      Unlimited before 0.6.3; 6 as of 0.6.3; Increased in version 0.9. Leasesets larger than 6 should be used with caution, as each lease adds 44 bytes, and routers older than version 0.9 will not be able to connect as they will throw an exception in readBytes(). Also, the churn will be quite rapid, leading to frequent netdb stores and transmission on existing connections. However we increase it now in case some hugely popular eepsite arrives. Strategies elsewhere in the router to efficiently handle large leasesets are TBD.
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### LeaseSet

          public LeaseSet()

  - ### Method Detail

    - #### addLease

          public void addLease(Lease lease)

      Adds a lease to this leaseset.
      Throws:
        `IllegalStateException` - if already signed

    - #### encrypt

          public void encrypt(SessionKey key)

      Encrypt the gateway and tunnel ID of each lease, leaving the expire dates unchanged. This adds an extra dummy lease, because AES data must be padded to 16 bytes. The fact that it is encrypted is not stored anywhere. Must be called after all the leases are in place, but before sign().

    - #### equals

          public boolean equals(Object object)

      Overrides:
        `equals` in class `Object`

    - #### getBytes

          protected byte[] getBytes()

      without sig!
      Specified by:
        `getBytes` in class `DatabaseEntry`
      Returns:
        the raw payload data, or null on error (for example, if this is a RouterInfo, a DataFormatException is thrown instead)

    - #### getDate

          public long getDate()

      Same as getEarliestLeaseDate()
      Specified by:
        `getDate` in class `DatabaseEntry`

    - #### getDestination

          public Destination getDestination()

      Warning - will be null for LS2 EncryptedLeaseSets if not decrypted
      Returns:
        Destination or null

    - #### getEarliestLeaseDate

          public long getEarliestLeaseDate()

      Retrieve the end date of the earliest lease included in this leaseSet. This is the date that should be used in comparisons for leaseSet age - to determine which LeaseSet was published more recently (later earliestLeaseSetDate means it was published later) Warning - do not use this for version comparison for LeaseSet2. Use LeaseSet2.getPublished() instead.
      Returns:
        earliest end date of any lease in the set, or -1 if there are no leases

    - #### getEncryptionKey

          public PublicKey getEncryptionKey()

    - #### getEncryptionKey

          public PublicKey getEncryptionKey(Set<EncType> supported)

      If more than one key, return the first supported one. If none supported, return null.
      Parameters:
        `supported` - what return types are allowed
      Returns:
        ElGamal key or null if ElGamal not in supported

    - #### getKeysAndCert

          public KeysAndCert getKeysAndCert()

      Description copied from class: `DatabaseEntry`
      Get the keys and the cert Identical to getDestination() in LeaseSet, and getIdentity() in RouterInfo.
      Specified by:
        `getKeysAndCert` in class `DatabaseEntry`
      Returns:
        KAC or null

    - #### getLatestLeaseDate

          public long getLatestLeaseDate()

      Retrieve the end date of the latest lease included in this leaseSet. This is the date used in isCurrent().
      Returns:
        latest end date of any lease in the set, or 0 if there are no leases

    - #### getLease

          public Lease getLease(int index)

    - #### getLeaseCount

          public int getLeaseCount()

      Gets the number of leases in this leaseset.
      Returns:
        0-16 A LeaseSet with no leases is revoked.

    - #### getSigningKey

          public SigningPublicKey getSigningKey()

      The revocation key. Undeprecated as of 0.9.38, used for the blinded key in EncryptedLeaseSet.
      Returns:
        the revocation key for LS1, null for LS2 except blinded key for encrypted LS2

    - #### getType

          public int getType()

      Description copied from class: `DatabaseEntry`
      Get the type of the data structure. This should be faster than instanceof.
      Specified by:
        `getType` in class `DatabaseEntry`
      Returns:
        KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET or LS2 types

    - #### hashCode

          public int hashCode()

      the destination has enough randomness in it to use it by itself for speed
      Overrides:
        `hashCode` in class `Object`

    - #### isCurrent

          public boolean isCurrent(long fudge)

      Determine whether ANY lease is currently valid, at least within a given fudge factor
      Parameters:
        `fudge` - milliseconds fudge factor to allow between the current time
      Returns:
        true if there are current leases, false otherwise

    - #### readBytes

          public void readBytes(InputStream in)
                         throws DataFormatException,
                                IOException

      This does NOT validate the signature
      Parameters:
        `in` - stream to read from
      Throws:
        `IllegalStateException` - if called more than once or Destination already set
        `DataFormatException` - if the data is improperly formatted
        `IOException` - if there was a problem reading the stream

    - #### setDestination

          public void setDestination(Destination dest)

      Sets the destination for this leaseset.
      Throws:
        `IllegalStateException` - if already signed

    - #### setEncryptionKey

          public void setEncryptionKey(PublicKey encryptionKey)

      Sets the encryption key for this leaseset.
      Throws:
        `IllegalStateException` - if already signed

    - #### setReceivedBy

          public void setReceivedBy(Hash localClient)

      As of 0.9.65, no longer sets receivedAsReply to true
      Overrides:
        `setReceivedBy` in class `DatabaseEntry`
      Parameters:
        `localClient` - may be null

    - #### setSigningKey

          public void setSigningKey(SigningPublicKey key)

      The revocation key. Unused except for encrypted LS2. Must be the same type as the Destination's SigningPublicKey.
      Throws:
        `IllegalArgumentException` - if different type

    - #### size

          public int size()

      Number of bytes, NOT including signature

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `Object`

    - #### verifySignature

          public boolean verifySignature()

      Verify that the signature matches the leaseset's destination's signing public key. As of 0.9.47, revocation is not checked.
      Overrides:
        `verifySignature` in class `DatabaseEntry`
      Returns:
        true only if the signature matches

    - #### writeBytes

          public void writeBytes(OutputStream out)
                          throws DataFormatException,
                                 IOException

      This does NOT validate the signature
      Parameters:
        `out` - stream to write to
      Throws:
        `DataFormatException` - if the data was incomplete or not yet ready to be written
        `IOException` - if there was a problem writing to the stream