- All Implemented Interfaces:
Serializable, DataStructure
- Direct Known Subclasses:
LeaseSet2
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
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:
Field Summary
Modifier and TypeFieldDescriptionprotected byte[]Cached serialized byte array for performance.protected booleanWhether decryption has been attempted.private booleanWhether decryption was successful.Decrypted leases backing store.protected DestinationDestination this LeaseSet is for.protected PublicKeyEncryption public key for the destination.private longEarliest expiration time among all leases.protected longLatest expiration time among all leases.Leases must stay in the order received, or signature verification will fail.protected SigningPublicKeyRevocation or blinded signing key.private static final intCombined length of gateway hash and tunnel ID.private static final intAES initialization vector length in bytes.static final intUnlimited before 0.6.3; 6 as of 0.6.3; Increased in version 0.9.Fields inherited from class 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_RECORDModifier and TypeFieldDescriptionprotected SignatureCryptographic signature.static final intEncrypted LeaseSet 2 type.static final intLeaseSet (v1) type.static final intLeaseSet 2 type.static final intMeta LeaseSet 2 type.static final intRouter info type.static final intService list type.static final intService record type.Constructor Summary
ConstructorsMethod Summary
Modifier and TypeMethodDescriptionvoidAdds a lease to this leaseset.private voiddecrypt(SessionKey key) Decrypt the leases, except for the last one which is partially padding.private voidencryp(SessionKey key) Encrypts the lease set in seven steps.voidencrypt(SessionKey key) Encrypt the gateway and tunnel ID of each lease, leaving the expire dates unchanged.booleanprotected byte[]getBytes()Without the signature!longgetDate()Same asgetEarliestLeaseDate().Warning - will be null for LS2 EncryptedLeaseSets if not decrypted.longRetrieve the end date of the earliest lease included in this leaseSet.Encryption public key.getEncryptionKey(Set<EncType> supported) If more than one key, return the first supported one.Keys and certificate for this lease set.longRetrieve the end date of the latest lease included in this leaseSet.getLease(int index) Lease at the given index.intNumber of leases in this leaseset.The revocation key.intgetType()Lease set type for the network database.inthashCode()The destination has enough randomness in it to use it by itself for speed.booleanisCurrent(long fudge) Determine whether ANY lease is currently valid, at least within a given fudge factor.private booleanTrue if it was encrypted, and we decrypted it successfully.voidreadBytes(InputStream in) This does NOT validate the signature.voidsetDestination(Destination dest) Destination for this leaseset.voidsetEncryptionKey(PublicKey encryptionKey) Encryption public key for this leaseset.voidsetReceivedBy(Hash localClient) Record the local client that received this leaseset.voidThe revocation key.intsize()Number of bytes, NOT including signature.toString()booleanVerify that the signature matches the leaseset's destination's signing public key.voidwriteBytes(OutputStream out) This does NOT validate the signature.Methods inherited from class DatabaseEntry
getHash, getReceivedAsPublished, getReceivedAsReply, getReceivedBy, getRoutingKey, getSignature, getSigningPublicKey, isLeaseSet, isLeaseSet, isRouterInfo, setReceivedAsPublished, setReceivedAsReply, setSignature, sign, validateRoutingKeyModifier and TypeMethodDescriptiongetHash()A common interface to the Hash of the two subclasses.booleanIf true, we received this LeaseSet by a remote peer publishing it to us, rather than by searching for it ourselves or locally creating it.booleanIf true, we received this LeaseSet by searching for it Default false.The Hash of the local client that received this LS, null if the router or unknown.Routing key for the structure using the current modifier in the RoutingKeyGenerator.Retrieve the proof that the identity stands behind the info here.protected SigningPublicKeyIdentical to getDestination().DatabaseEntry.getSigningPublicKey()in LeaseSet, and getIdentity().getSigningPublicKey() in RouterInfo.booleanConvenience method, is the type any variant of leaseset?static booleanisLeaseSet(int type) Convenience method, is the type any variant of leaseset?booleanConvenience method, is the type any variant of router info?voidMarks this entry as received via published mode.voidMarks this entry as received via reply.voidsetSignature(Signature signature) Configure the proof that the entity stands behind the info here.voidsign(SigningPrivateKey key) Sign the structure using the supplied signing key.booleanValidates the routing key for this entry.Methods inherited from class DataStructureImpl
calculateHash, fromBase64, fromByteArray, read, toBase64, toByteArrayModifier and TypeMethodDescriptionCalculate the SHA256 value of this object (useful for a few scenarios).voidfromBase64(String data) Load the structure from the provided base64 string.voidfromByteArray(byte[] data) Loads structure from the data providedprotected intread(InputStream in, byte[] target) Repeated reads until buffer is full or IOException is thrown.toBase64()Render the structure into modified base 64 notation.byte[]Convert the structure to a byte array.
Field Details
_destination
Destination this LeaseSet is for._encryptionKey
Encryption public key for the destination._signingKey
Revocation or blinded signing key. For LS1, the revocation key; for LS2, null except the blinded key for encrypted LS2._leases
_firstExpiration
private long _firstExpirationEarliest expiration time among all leases. Cached becauseisCurrent(long)and getEarliestLeaseDate() are called frequently._lastExpiration
protected long _lastExpirationLatest expiration time among all leases._decryptedLeases
_decrypted
private boolean _decryptedWhether decryption was successful._checked
protected boolean _checkedWhether decryption has been attempted._byteified
protected volatile byte[] _byteifiedCached serialized byte array for performance.MAX_LEASES
public static final int MAX_LEASESUnlimited 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(InputStream). 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:
DATA_LEN
private static final int DATA_LENCombined length of gateway hash and tunnel ID.- See Also:
IV_LEN
private static final int IV_LENAES initialization vector length in bytes.- See Also:
Constructor Details
LeaseSet
public LeaseSet()Creates a new leaseset with default values.
Method Details
getDate
public long getDate()Same asgetEarliestLeaseDate().- Specified by:
getDatein classDatabaseEntry- Returns:
- milliseconds since the epoch of the earliest lease expiry
getKeysAndCert
Keys and certificate for this lease set.- Specified by:
getKeysAndCertin classDatabaseEntry- Returns:
- KAC or null
getType
public int getType()Lease set type for the network database.- Specified by:
getTypein classDatabaseEntry- Returns:
- KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET or LS2 types
getDestination
Warning - will be null for LS2 EncryptedLeaseSets if not decrypted.- Returns:
- Destination or null
setDestination
Destination for this leaseset.- Parameters:
dest- the destination this leaseset is published under- Throws:
IllegalStateException- if already signed
getEncryptionKey
getEncryptionKey
setEncryptionKey
Encryption public key for this leaseset.- Parameters:
encryptionKey- the ElGamal or ECIES key tunnel build requests are encrypted to, matched to the receiver by the key type- Throws:
IllegalStateException- if already signed
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
setSigningKey
The revocation key. Unused except for encrypted LS2. Must be the same type as the Destination's SigningPublicKey.- Parameters:
key- the revocation key, which must match the signing public key type of the destination or the leaseset cannot be verified- Throws:
IllegalArgumentException- if different type
setReceivedBy
Record the local client that received this leaseset.As of 0.9.65, no longer sets receivedAsReply to true.
- Overrides:
setReceivedByin classDatabaseEntry- Parameters:
localClient- may be null
addLease
Adds a lease to this leaseset.- Parameters:
lease- the lease to add, which must have a gateway and, outside a meta LeaseSet2, a tunnel ID- Throws:
IllegalStateException- if already signed
getLeaseCount
public int getLeaseCount()Number of leases in this leaseset.- Returns:
- 0-16 A LeaseSet with no leases is revoked.
getLease
Lease at the given index.- Parameters:
index- the lease index- Returns:
- the decrypted lease when encrypted, otherwise the stored one
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
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
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:
verifySignaturein classDatabaseEntry- Returns:
- true only if the signature matches
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
getBytes
protected byte[] getBytes()Without the signature!- Specified by:
getBytesin classDatabaseEntry- Returns:
- the raw payload data, or null on error (for example, if this is a RouterInfo, a DataFormatException is thrown instead)
readBytes
This does NOT validate the signature.- Parameters:
in- stream to read from- Throws:
IllegalStateException- if called more than once or Destination already setDataFormatException- if the data is improperly formattedIOException- if there was a problem reading the stream
writeBytes
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 writtenIOException- if there was a problem writing to the stream
size
public int size()Number of bytes, NOT including signature.- Returns:
- the size in bytes
equals
hashCode
toString
encrypt
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().- Parameters:
key- the session key whose first block is the AES key, with the remainder used to derive the initialization vector
encryp
Encrypts the lease set in seven steps.- Put the {Gateway Hash, TunnelID} pairs for all the leases in a buffer
- Pad with random data to a multiple of 16 bytes
- Use the first part of the dest's public key as an IV
- Encrypt
- Pad with random data to a multiple of 36 bytes
- Add an extra lease
- Replace the Hash and TunnelID in each Lease
- Parameters:
key- the AES session key to encrypt the lease data with- Throws:
DataFormatException- if a lease's gateway or tunnel ID is not setIOException- if the lease data cannot be written
decrypt
Decrypt the leases, except for the last one which is partially padding. Store the new decrypted leases in a backing store, and keep the original leases so that verify() still works and the encrypted leaseset can be sent on to others (viawriteBytes(OutputStream)).- Parameters:
key- the AES session key to decrypt the lease data with- Throws:
DataFormatException- if there are fewer than two leases, or the data is invalidIOException- if the lease data cannot be read
isEncrypted
private boolean isEncrypted()True if it was encrypted, and we decrypted it successfully.- Returns:
- true if it was encrypted, and we decrypted it successfully. Decrypts on first call.