Documentation
¶
Overview ¶
Package lease_set2 implements the I2P LeaseSet2 common data structure
Package lease_set2 implements the I2P LeaseSet2 common data structure as specified in I2P specification 0.9.67.
LeaseSet2 (DatabaseStore type 3, introduced in spec 0.9.38) is the modern replacement for the legacy LeaseSet, providing enhanced features including multiple encryption keys, compact Lease2 structures, service discovery options, and optional offline signature support.
The package provides:
- Parsing via ReadLeaseSet2
- Construction via NewLeaseSet2
- Serialization via Bytes
- Signature verification via Verify
- Structural validation via Validate
https://geti2p.net/spec/common-structures#leaseset2
Package lease_set2 implements the I2P LeaseSet2 common data structure
Package lease_set2 implements the I2P LeaseSet2 common data structure
Package lease_set2 implements the I2P LeaseSet2 common data structure
Index ¶
- Constants
- type EncryptionKey
- type LeaseSet2
- func (ls2 *LeaseSet2) ApplyCommonFields(fields rootcommon.LeaseSetCommonFields)
- func (ls2 *LeaseSet2) Bytes() ([]byte, error)
- func (ls2 *LeaseSet2) Destination() destination.Destination
- func (ls2 *LeaseSet2) EncryptionKeyCount() int
- func (ls2 *LeaseSet2) EncryptionKeys() []EncryptionKey
- func (ls2 *LeaseSet2) Equals(other *LeaseSet2) bool
- func (ls2 *LeaseSet2) ExpirationTime() time.Time
- func (ls2 *LeaseSet2) Expires() uint16
- func (ls2 *LeaseSet2) Flags() uint16
- func (ls2 *LeaseSet2) HasOfflineKeys() bool
- func (ls2 *LeaseSet2) IsBlinded() bool
- func (ls2 *LeaseSet2) IsExpired() bool
- func (ls2 *LeaseSet2) IsUnpublished() bool
- func (ls2 *LeaseSet2) IsValid() bool
- func (ls2 *LeaseSet2) LeaseCount() int
- func (ls2 *LeaseSet2) Leases() []lease.Lease2
- func (ls2 *LeaseSet2) OfflineSignature() *offline_signature.OfflineSignature
- func (ls2 *LeaseSet2) Options() common.Mapping
- func (ls2 *LeaseSet2) Published() uint32
- func (ls2 *LeaseSet2) PublishedTime() time.Time
- func (ls2 *LeaseSet2) Signature() sig.Signature
- func (ls2 *LeaseSet2) Validate() error
- func (ls2 *LeaseSet2) Verify() error
Constants ¶
const ( // LEASESET2_MIN_SIZE is the absolute minimum size for a LeaseSet2 structure. // This assumes: LeaseSet2Header (395 bytes) + empty options (2 bytes) + // 1 encryption key (5 bytes header + 32 bytes X25519) + 1 lease (1 byte count + 40 bytes Lease2) + signature (64 bytes EdDSA) // = 395 + 2 + 5 + 32 + 1 + 40 + 64 = 539 bytes minimum // Per spec: "All LeaseSet2 variants require at least one Lease." LEASESET2_MIN_SIZE = 539 // LEASESET2_DBSTORE_TYPE is the DatabaseStore type byte for LeaseSet2 (value 3). // Per the I2P spec the signature is computed over the serialised body PREPENDED // with this single byte: []byte{0x03} || Bytes()[:len-sigLen]. LEASESET2_DBSTORE_TYPE = 0x03 // LEASESET2_HEADER_MIN_SIZE is the minimum size of LeaseSet2Header without offline signature. // Destination (387 bytes) + published (4 bytes) + expires (2 bytes) + flags (2 bytes) // = 395 bytes LEASESET2_HEADER_MIN_SIZE = 395 // LEASESET2_MIN_DESTINATION_SIZE is the minimum size for a valid I2P Destination. // This is 387 bytes: 384 bytes for KeysAndCert data + minimum 3 bytes for certificate. LEASESET2_MIN_DESTINATION_SIZE = 387 // LEASESET2_PUBLISHED_SIZE is the size of the published timestamp field (4 bytes, seconds since epoch). LEASESET2_PUBLISHED_SIZE = 4 // LEASESET2_EXPIRES_SIZE is the size of the expires offset field (2 bytes, offset from published in seconds). // Maximum offset is 65535 seconds (18.2 hours), but typically limited to ~660 seconds (11 minutes). LEASESET2_EXPIRES_SIZE = 2 // LEASESET2_FLAGS_SIZE is the size of the flags field (2 bytes). LEASESET2_FLAGS_SIZE = 2 // LEASESET2_ENCRYPTION_KEY_TYPE_SIZE is the size of each encryption key type field (2 bytes). LEASESET2_ENCRYPTION_KEY_TYPE_SIZE = 2 // LEASESET2_ENCRYPTION_KEY_LENGTH_SIZE is the size of each encryption key length field (2 bytes). LEASESET2_ENCRYPTION_KEY_LENGTH_SIZE = 2 // LEASESET2_MAX_LEASES is the maximum number of Lease2 structures allowed in a LeaseSet2 (16). // This is the same limit as legacy LeaseSet. LEASESET2_MAX_LEASES = 16 // LEASESET2_MAX_ENCRYPTION_KEYS is a reasonable upper limit for the number of encryption keys. // While the spec doesn't define a hard maximum, practical implementations support 1-4 keys. LEASESET2_MAX_ENCRYPTION_KEYS = 16 )
LeaseSet2 Structure Size Constants These constants define the minimum and maximum sizes for LeaseSet2 components according to I2P specification 0.9.67.
const ( // LEASESET2_FLAG_OFFLINE_KEYS indicates that an offline signature is present (bit 0). // When set, the LeaseSet2Header contains an OfflineSignature structure. LEASESET2_FLAG_OFFLINE_KEYS = 1 << 0 // 0x0001 // LEASESET2_FLAG_UNPUBLISHED indicates this is an unpublished leaseset (bit 1). // Unpublished leasesets should not be flooded, published, or sent in response to queries. // If expired, do not query the netdb for a new one unless FLAG_BLINDED is also set. LEASESET2_FLAG_UNPUBLISHED = 1 << 1 // 0x0002 // LEASESET2_FLAG_BLINDED indicates this leaseset will be blinded and encrypted when published (bit 2). // If set, bit 1 (UNPUBLISHED) should also be set. // If this leaseset expires, query the blinded location in the netdb. // Introduced in I2P version 0.9.42. LEASESET2_FLAG_BLINDED = 1 << 2 // 0x0004 )
LeaseSet2 Flags Constants These constants define the bit flags used in the LeaseSet2 flags field.
const ( // LEASESET2_MAX_EXPIRES_OFFSET is the maximum value that can be stored in the expires field (2 bytes). // This represents 65535 seconds or approximately 18.2 hours. LEASESET2_MAX_EXPIRES_OFFSET = 65535 // LEASESET2_TYPICAL_MAX_EXPIRES is the typical maximum expiration offset for LeaseSet2 (660 seconds = 11 minutes). // While the field supports up to 18.2 hours, most implementations limit this to ~11 minutes. LEASESET2_TYPICAL_MAX_EXPIRES = 660 // METALEASESET_MAX_EXPIRES is the maximum expiration offset for MetaLeaseSet (65535 seconds = 18.2 hours). // MetaLeaseSet can use the full range of the expires field. METALEASESET_MAX_EXPIRES = 65535 )
LeaseSet2 Expiration Constants These constants define typical expiration time limits for LeaseSet2 structures.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type EncryptionKey ¶
type EncryptionKey struct {
KeyType uint16 // Encryption key type (2 bytes) - see key_certificate constants
KeyLen uint16 // Length of the key data (2 bytes)
KeyData []byte // Encryption key data (keyLen bytes)
}
EncryptionKey represents a single encryption key entry in LeaseSet2. Each entry contains the key type, length, and the actual key data.
func (EncryptionKey) Bytes ¶ added in v0.1.5
func (ek EncryptionKey) Bytes() []byte
Bytes serializes the EncryptionKey into its wire format: 2-byte key type + 2-byte key length + key data.
func (EncryptionKey) String ¶ added in v0.1.5
func (ek EncryptionKey) String() string
String returns a human-readable representation of the EncryptionKey for debugging and logging purposes.
type LeaseSet2 ¶
type LeaseSet2 struct {
// contains filtered or unexported fields
}
LeaseSet2 represents an I2P LeaseSet2 structure introduced in specification 0.9.38. LeaseSet2 is the modern replacement for the legacy LeaseSet, providing enhanced features:
- Multiple encryption keys per leaseset for crypto agility
- More compact Lease2 structures with 4-byte timestamps
- Service record options for DNS-SD style service discovery
- Optional offline signature support for enhanced security
- Published timestamp field for better versioning
https://geti2p.net/spec/common-structures#leaseset2
func NewLeaseSet2 ¶ added in v0.0.4
func NewLeaseSet2( dest destination.Destination, published uint32, expiresOffset uint16, flags uint16, offlineSig *offline_signature.OfflineSignature, options common.Mapping, encryptionKeys []EncryptionKey, leases []lease.Lease2, signingKey interface{}, ) (LeaseSet2, error)
NewLeaseSet2 creates a new LeaseSet2 from the provided components and signs it.
This constructor creates a complete, signed LeaseSet2 structure ready for network publication. It validates all inputs, constructs the LeaseSet2 data structure, and generates the cryptographic signature using the provided signing key.
Parameters:
- dest: Destination containing signing and encryption keys for this service
- published: Publication timestamp (seconds since Unix epoch)
- expiresOffset: Expiration offset in seconds from published time (max 65535)
- flags: LeaseSet2 flags (OFFLINE_KEYS, UNPUBLISHED, BLINDED)
- offlineSig: Optional offline signature (nil if not using offline keys)
- options: Service discovery options mapping (can be nil for no options)
- encryptionKeys: List of encryption keys (1-16 keys required)
- leases: List of Lease2 structures (0-16 leases allowed)
- signingKey: Private key for signing the LeaseSet2
Returns:
- LeaseSet2: Constructed and signed LeaseSet2
- error: nil on success, validation or signing error otherwise
Example:
ls2, err := NewLeaseSet2(
destination,
uint32(time.Now().Unix()),
600, // expires in 10 minutes
0, // no special flags
nil, // no offline signature
nil, // no options
[]EncryptionKey{{keyType: X25519, keyLen: 32, keyData: myKey}},
[]lease.Lease2{lease1, lease2},
myPrivateKey,
)
func NewLeaseSet2FromBytes ¶ added in v0.1.5
NewLeaseSet2FromBytes is a convenience constructor that parses a LeaseSet2 from raw bytes. It is equivalent to calling ReadLeaseSet2 but returns a pointer and discards the remainder, matching the NewXFromBytes pattern used by other packages in this codebase.
func ReadLeaseSet2 ¶
ReadLeaseSet2 parses a LeaseSet2 structure from the provided byte slice. Returns the parsed LeaseSet2, remaining bytes, and any error encountered.
The parsing process:
- Parse destination (387+ bytes)
- Parse published timestamp (4 bytes)
- Parse expires offset (2 bytes)
- Parse flags (2 bytes)
- If flags bit 0 set, parse offline signature (variable length)
- Parse options mapping (variable length, 2+ bytes)
- Parse encryption keys (1+ keys, variable length)
- Parse Lease2 structures (0+ leases, 40 bytes each)
- Parse signature (variable length based on signature type)
Returns error if:
- Data is too short for minimum LeaseSet2 size
- Destination parsing fails
- Any component parsing fails
- Number of encryption keys or leases exceeds maximum allowed
func (*LeaseSet2) ApplyCommonFields ¶ added in v0.1.5
func (ls2 *LeaseSet2) ApplyCommonFields(fields rootcommon.LeaseSetCommonFields)
ApplyCommonFields stores the parsed common header fields into the LeaseSet2, satisfying the rootcommon.LeaseSetFieldApplier interface to eliminate duplicated field assignment code shared with MetaLeaseSet.
func (*LeaseSet2) Bytes ¶ added in v0.0.6
Bytes returns the complete LeaseSet2 structure as a byte array. This serializes all components in the proper order according to I2P specification 0.9.67.
The serialization includes:
- Destination (387+ bytes)
- Published timestamp (4 bytes)
- Expires offset (2 bytes)
- Flags (2 bytes)
- Offline signature if present (variable length)
- Options mapping (2+ bytes)
- Encryption keys with count (5+ bytes per key)
- Lease2 structures with count (40 bytes per lease)
- Signature (variable length)
Note: the signature was computed over []byte{LEASESET2_DBSTORE_TYPE} || Bytes()[:len-sigLen], i.e. a single 0x03 byte is prepended to all content before signing. External verifiers must include this prefix when reconstructing the signed payload.
Returns the serialized LeaseSet2 or error if serialization fails.
func (*LeaseSet2) Destination ¶
func (ls2 *LeaseSet2) Destination() destination.Destination
Destination returns the destination identity associated with this LeaseSet2. The destination contains the signing and encryption public keys for the service.
func (*LeaseSet2) EncryptionKeyCount ¶
EncryptionKeyCount returns the number of encryption keys in this LeaseSet2.
func (*LeaseSet2) EncryptionKeys ¶
func (ls2 *LeaseSet2) EncryptionKeys() []EncryptionKey
EncryptionKeys returns the slice of encryption keys. Keys are in order of server preference, most-preferred first.
func (*LeaseSet2) Equals ¶ added in v0.1.5
Equals compares two LeaseSet2 structures for equality by comparing their serialized byte representations. Returns true if both produce identical bytes.
func (*LeaseSet2) ExpirationTime ¶
ExpirationTime returns the absolute expiration time as a Go time.Time value. This is calculated as PublishedTime() + Expires() seconds.
func (*LeaseSet2) Expires ¶
Expires returns the expiration offset in seconds from the published timestamp. The actual expiration time is Published() + Expires().
func (*LeaseSet2) Flags ¶
Flags returns the raw flags value (2 bytes). Use HasOfflineKeys(), IsUnpublished(), IsBlinded() for flag checking.
func (*LeaseSet2) HasOfflineKeys ¶
HasOfflineKeys returns true if the offline signature flag is set (bit 0). When true, the OfflineSignature field will be populated.
func (*LeaseSet2) IsBlinded ¶
IsBlinded returns true if the blinded flag is set (bit 2). When set, this unencrypted leaseset will be blinded and encrypted when published. Introduced in I2P version 0.9.42.
func (*LeaseSet2) IsExpired ¶
IsExpired checks if the LeaseSet2 has expired based on the current time. Returns true if the current time is after the expiration time.
func (*LeaseSet2) IsUnpublished ¶
IsUnpublished returns true if the unpublished flag is set (bit 1). Unpublished leasesets should not be flooded or published to the network database.
func (*LeaseSet2) IsValid ¶ added in v0.1.5
IsValid returns true if the LeaseSet2 passes structural validation.
func (*LeaseSet2) LeaseCount ¶
LeaseCount returns the number of Lease2 structures in this LeaseSet2.
func (*LeaseSet2) OfflineSignature ¶
func (ls2 *LeaseSet2) OfflineSignature() *offline_signature.OfflineSignature
OfflineSignature returns the optional offline signature structure. Returns nil if HasOfflineKeys() is false.
func (*LeaseSet2) Options ¶
Options returns the mapping containing service record options. Options are used for DNS-SD style service discovery.
func (*LeaseSet2) Published ¶
Published returns the published timestamp as a uint32 (seconds since Unix epoch). This timestamp indicates when the LeaseSet2 was created/published.
func (*LeaseSet2) PublishedTime ¶
PublishedTime returns the published timestamp as a Go time.Time value. Converts the 4-byte second timestamp to time.Time in UTC timezone.
func (*LeaseSet2) Signature ¶
Signature returns the signature over the LeaseSet2 data. The signature is created by the destination's signing key or the transient key if offline signature is present.
func (*LeaseSet2) Validate ¶ added in v0.1.5
Validate checks the structural integrity of the LeaseSet2. It verifies:
- At least 1 encryption key is present
- Encryption key count does not exceed maximum
- Each encryption key has consistent KeyLen and KeyData length
- Each encryption key's KeyLen matches the expected size for its KeyType
- Offline signature flag is consistent with OfflineSignature presence
- Reserved flag bits are zero
- Options mapping keys are sorted per spec (for signature invariance)
Returns nil if valid, or an error describing the first issue found.
func (*LeaseSet2) Verify ¶ added in v0.1.5
Verify verifies the cryptographic signature of the LeaseSet2.
Per the I2P specification, the signature for a LeaseSet2 is computed over the serialised content PREPENDED with a single byte containing the DatabaseStore type (0x03). The verified data is:
[]byte{0x03} + Bytes()[:len(Bytes()) - signatureLength]
If HasOfflineKeys() is true, Verify additionally checks that the offline signature authorization chain is valid: the transient signing key must have been signed by the Destination's long-term signing private key. Only after that chain check passes is the body signature verified against the transient key. This prevents a forged transient key from being trusted.
Returns nil if the signature is valid, or an error describing the failure.