All Implemented Interfaces:
Serializable, DataStructure
Direct Known Subclasses:
EncryptedLeaseSet, MetaLeaseSet

public class LeaseSet2extends LeaseSet
Implementation of LeaseSet2 as specified in Proposal 123: New NetDb Entries.

LeaseSet2 provides several enhancements over the original LeaseSet format:

  • Support for multiple encryption keys with server preference ordering
  • Offline signature support for reduced router load
  • Published and expiration timestamps independent of lease times
  • Options and statistics support
  • Blinded and encrypted LeaseSet support

Key differences from LeaseSet:

See Also:
  • Field Details

    • _flags

      protected int _flags
      Flags for options, offline, unpublished, blinded.
    • _published

      protected long _published
      Published timestamp in ms (1-second resolution).
    • _expires

      protected long _expires
      Expiration timestamp in ms (1-second resolution).
    • _transientExpires

      protected long _transientExpires
      Transient key expiration in ms.
    • _transientSigningPublicKey

      protected SigningPublicKey _transientSigningPublicKey
      Transient signing public key for offline signing.
    • _offlineSignature

      protected Signature _offlineSignature
      Offline signature.
    • _options

      protected Properties _options
      Options and statistics properties, may be null.
  • Constructor Details

    • LeaseSet2

      public LeaseSet2()
      Creates a new LeaseSet2 with default values.
  • Method Details

    • getPublished

      public long getPublished()
      Published timestamp, as received. Different than getDate() or getEarliestLeaseDate(), which are the earliest lease expiration.

      Use this for LS2 version comparison, NOT getEarliestLeaseDate(), because that will return -1 for EncryptedLS and MetaLS.

      Returns:
      in ms, with 1 second resolution
    • setPublished

      public void setPublished(long now)
      Published timestamp. Will be rounded to nearest second. If not called, will be set on write.
      Parameters:
      now - the publication time in milliseconds since the epoch, rounded to the nearest second before being stored
    • getExpires

      public long getExpires()
      Published expiration, as received. May be different than getLatestLeaseDate(), which is the latest lease expiration.
      Returns:
      in ms, with 1 second resolution
    • isUnpublished

      public boolean isUnpublished()
      True if unpublished.
      Returns:
      true if unpublished
    • setUnpublished

      public void setUnpublished()
      Marks this leaseset as unpublished.
      Throws:
      IllegalStateException - if already signed
    • isBlindedWhenPublished

      public boolean isBlindedWhenPublished()
      Whether the unencrypted LS, when published, will be blinded/encrypted.
      Returns:
      whether blinded when published
    • setBlindedWhenPublished

      public void setBlindedWhenPublished()
      Mark the unencrypted LS to be blinded/encrypted when published.
      Throws:
      IllegalStateException - if already signed
    • getReceivedAsPublished

      public boolean getReceivedAsPublished()
      If true, we received this LeaseSet by a remote peer publishing it to us, AND the unpublished flag is not set. Default false.
      Overrides:
      getReceivedAsPublished in class DatabaseEntry
      Returns:
      the received as published
    • getOption

      public String getOption(String opt)
      Option value for the given key.
      Parameters:
      opt - the option key
      Returns:
      the option value, or null if not found
    • getOptions

      public Properties getOptions()
      Leaseset options.
      Returns:
      not a copy, do not modify, or null
    • getEncryptionKey

      public PublicKey getEncryptionKey()
      If more than one key, return the first supported one. If none supported, return the first one.
      Overrides:
      getEncryptionKey in class LeaseSet
      Returns:
      the encryption key
    • getEncryptionKey

      public PublicKey getEncryptionKey(Set<EncType> supported)
      If more than one key, return the first supported one. If none supported, return null.
      Overrides:
      getEncryptionKey in class LeaseSet
      Parameters:
      supported - what return types are allowed
      Returns:
      first supported key or null
    • addEncryptionKey

      public void addEncryptionKey(PublicKey key)
      Add an encryption key.

      Encryption keys should be added in order of server preference, most-preferred first.

      Parameters:
      key - the key to append; the first one added becomes the key returned by getEncryptionKey()
    • getEncryptionKeys

      public List<PublicKey> getEncryptionKeys()
      This returns all the keys. getEncryptionKey() returns the first one.

      Encryption keys should be in order of server preference, most-preferred first. Client behavior should be to select the first key with a supported encryption type. Clients may use other selection algorithms based on encryption support, relative performance, and other factors.

      Returns:
      not a copy, do not modify, null if none
    • setOptions

      public void setOptions(Properties options)
      Configure a set of options or statistics that the router can expose. Makes a copy, and replaces any options set previously.
      Parameters:
      options - if null, clears current options
      Throws:
      IllegalStateException - if LeaseSet2 is already signed
    • isOffline

      public boolean isOffline()
      Checks if this leaseset uses offline keys.
      Returns:
      true if the leaseset is signed with transient offline keys
    • getTransientSigningKey

      public SigningPublicKey getTransientSigningKey()
      Transient public key for offline signing.
      Returns:
      transient public key or null if not offline signed
    • getTransientExpiration

      public long getTransientExpiration()
      Absolute time, not time from now.
      Returns:
      transient expiration time or 0 if not offline signed
    • setOfflineSignature

      public boolean setOfflineSignature(long expires, SigningPublicKey transientSPK, Signature offlineSig)
      Destination must be previously set.
      Parameters:
      expires - when the offline signature stops being valid, in milliseconds since the epoch
      transientSPK - the key that will sign the leaseset
      offlineSig - the signature by the spk in the destination
      Returns:
      success, false if verify failed or expired
      Throws:
      IllegalStateException - if already signed
    • offlineSign

      public static Signature offlineSign(long expires, SigningPublicKey transientSPK, SigningPrivateKey priv)
      Parameters:
      expires - when the offline signature stops being valid, in milliseconds since the epoch; the signature covers whole seconds only
      transientSPK - the key that will sign the leaseset
      priv - the private signing key for the destination
      Returns:
      null on error
    • verifyOfflineSignature

      public boolean verifyOfflineSignature()
      Verify the offline signature.
      Returns:
      true if valid
    • verifyOfflineSignature

      protected boolean verifyOfflineSignature(SigningPublicKey spk)
      Verify the offline signature with the given key.
      Parameters:
      spk - the key to verify against
      Returns:
      true if valid
    • setBlindedHash

      public void setBlindedHash(Hash bh)
      Blinded hash, if known at creation.
      Parameters:
      bh - the blinded hash of this leaseset's destination, as computed at creation time for an encrypted LeaseSet2
    • getBlindedHash

      public Hash getBlindedHash()
      The original blinded hash, where this came from.
      Returns:
      null if unknown or not previously blinded
    • getType

      public int getType()
      Lease set type for the network database.
      Overrides:
      getType in class LeaseSet
      Returns:
      KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET or LS2 types
    • setSigningKey

      public void setSigningKey(SigningPublicKey key)
      The revocation key. Overridden to do nothing, as we're using the _signingKey field for the blinded key in Enc LS2.
      Overrides:
      setSigningKey in class LeaseSet
      Parameters:
      key - the revocation key, which must match the signing public key type of the destination or the leaseset cannot be verified
    • isCurrent

      public boolean isCurrent(long fudge)
      Determine whether the leaseset is currently valid, at least within a given fudge factor. Overridden to use the expiration time instead of the last expiration.
      Overrides:
      isCurrent in class LeaseSet
      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!
      Overrides:
      getBytes in class LeaseSet
      Returns:
      the raw payload data, or null on error (for example, if this is a RouterInfo, a DataFormatException is thrown instead)
    • readBytes

      public void readBytes(InputStream in) throws DataFormatException, IOException
      This does NOT validate the signature.
      Specified by:
      readBytes in interface DataStructure
      Overrides:
      readBytes in class LeaseSet
      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
    • writeBytes

      public void writeBytes(OutputStream out) throws DataFormatException, IOException
      Including sig. This does NOT validate the signature.
      Specified by:
      writeBytes in interface DataStructure
      Overrides:
      writeBytes in class LeaseSet
      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
    • writeBytesWithoutSig

      protected void writeBytesWithoutSig(OutputStream out) throws DataFormatException, IOException
      Without sig. This does NOT validate the signature.
      Parameters:
      out - the stream to write the header and body to
      Throws:
      DataFormatException - if the destination or encryption key is unset
      IOException - if the stream cannot be written
    • writeBody

      protected void writeBody(OutputStream out) throws DataFormatException, IOException
      Without sig. This does NOT validate the signature.
      Parameters:
      out - the stream to write the properties, encryption keys and leases to
      Throws:
      DataFormatException - if the leases or a key cannot be serialized
      IOException - if the stream cannot be written
    • readHeader

      protected void readHeader(InputStream in) throws DataFormatException, IOException
      Read the LeaseSet2 header from a stream.
      Parameters:
      in - the input stream
      Throws:
      DataFormatException - if the data is invalid
      IOException - if there is an error reading
    • writeHeader

      protected void writeHeader(OutputStream out) throws DataFormatException, IOException
      Write the LeaseSet2 header to a stream.
      Parameters:
      out - the output stream
      Throws:
      DataFormatException - if the data is invalid
      IOException - if there is an error writing
    • readOfflineBytes

      protected void readOfflineBytes(InputStream in) throws DataFormatException, IOException
      Read the offline signing section from a stream.
      Parameters:
      in - the input stream
      Throws:
      DataFormatException - if the data is invalid
      IOException - if there is an error reading
    • writeOfflineBytes

      protected void writeOfflineBytes(OutputStream out) throws DataFormatException, IOException
      Write the offline signing section to a stream.
      Parameters:
      out - the output stream
      Throws:
      DataFormatException - if the data is invalid
      IOException - if there is an error writing
    • size

      public int size()
      Number of bytes, NOT including signature.
      Overrides:
      size in class LeaseSet
      Returns:
      the size in bytes
    • addLease

      public void addLease(Lease lease)
      Must be a Lease2.
      Overrides:
      addLease in class LeaseSet
      Parameters:
      lease - must be a Lease2
      Throws:
      IllegalArgumentException - if not a Lease2
    • sign

      public void sign(SigningPrivateKey key) throws DataFormatException
      Sign the structure using the supplied signing key. Overridden because LS2 sigs cover the type byte.
      Overrides:
      sign in class DatabaseEntry
      Parameters:
      key - the signing private key
      Throws:
      IllegalStateException - if already signed
      DataFormatException - if signing fails
    • verifySignature

      public boolean verifySignature()
      Verify with the SPK in the dest for online sigs. Verify with the SPK in the offline sig section for offline sigs.
      Overrides:
      verifySignature in class LeaseSet
      Returns:
      true if a non-RSA signature is present and verifies against the online or offline signing key as appropriate
    • equals

      public boolean equals(Object object)
      Overrides:
      equals in class LeaseSet
    • hashCode

      public int hashCode()
      The destination has enough randomness in it to use it by itself for speed.
      Overrides:
      hashCode in class LeaseSet
    • toString

      public String toString()
      Overrides:
      toString in class LeaseSet
    • 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().
      Overrides:
      encrypt in class LeaseSet
      Parameters:
      key - the session key whose first block is the AES key, with the remainder used to derive the initialization vector