Package net.i2p.data.i2np
Class BuildRequestRecord
- java.lang.Object
-
- net.i2p.data.i2np.BuildRequestRecord
-
public class BuildRequestRecord extends Object
As of 0.9.48, supports two formats. As of 0.9.51, supports three formats. The original 222-byte ElGamal format, the new 464-byte ECIES format, and the newest 154-byte ECIES format. See proposal 152 and 157 for details on the new formats. None of the readXXX() calls are cached. For efficiency, they should only be called once. Original ElGamal format: Holds the unencrypted 222-byte tunnel request record, with a constructor for ElGamal decryption and a method for ElGamal encryption. Iterative AES encryption/decryption is done elsewhere. Cleartext:bytes 0-3: tunnel ID to receive messages as bytes 4-35: local router identity hash (Unused and no accessor here) bytes 36-39: next tunnel ID bytes 40-71: next router identity hash bytes 72-103: AES-256 tunnel layer key bytes 104-135: AES-256 tunnel IV key bytes 136-167: AES-256 reply key bytes 168-183: reply IV byte 184: flags bytes 185-188: request time (in hours since the epoch) bytes 189-192: next message ID bytes 193-221: uninterpreted / random padding
Encrypted:bytes 0-15: First 16 bytes of router hash bytes 16-527: ElGamal encrypted block (discarding zero bytes at elg[0] and elg[257])
ECIES long record format, ref: proposal 152: Holds the unencrypted 464-byte tunnel request record, with a constructor for ECIES decryption and a method for ECIES encryption. Iterative AES encryption/decryption is done elsewhere. Cleartext:bytes 0-3: tunnel ID to receive messages as, nonzero bytes 4-7: next tunnel ID, nonzero bytes 8-39: next router identity hash bytes 40-71: AES-256 tunnel layer key bytes 72-103: AES-256 tunnel IV key bytes 104-135: AES-256 reply key bytes 136-151: AES-256 reply IV byte 152: flags bytes 153-155: more flags, unused, set to 0 for compatibility bytes 156-159: request time (in minutes since the epoch, rounded down) bytes 160-163: request expiration (in seconds since creation) bytes 164-167: next message ID bytes 168-x: tunnel build options (Mapping) bytes x-x: other data as implied by flags or options bytes x-463: random padding
Encrypted:bytes 0-15: Hop's truncated identity hash bytes 16-47: Sender's ephemeral X25519 public key bytes 48-511: ChaCha20 encrypted BuildRequestRecord bytes 512-527: Poly1305 MAC
ECIES short record format, ref: proposal 157: Holds the unencrypted 154-byte tunnel request record, with a constructor for ECIES decryption and a method for ECIES encryption. Iterative AES encryption/decryption is done elsewhere. Cleartext:bytes 0-3: tunnel ID to receive messages as, nonzero bytes 4-7: next tunnel ID, nonzero bytes 8-39: next router identity hash byte 40: flags bytes 41-42: more flags, unused, set to 0 for compatibility byte 43: layer enc. type bytes 44-47: request time (in minutes since the epoch, rounded down) bytes 48-51: request expiration (in seconds since creation) bytes 52-55: next message ID bytes 56-x: tunnel build options (Mapping) bytes x-x: other data as implied by flags or options bytes x-153: random padding
Encrypted:bytes 0-15: Hop's truncated identity hash bytes 16-47: Sender's ephemeral X25519 public key bytes 48-201: ChaCha20 encrypted BuildRequestRecord bytes 202-217: Poly1305 MAC
-
-
Field Summary
Fields Modifier and Type Field Description static int
IV_SIZE
static int
OFF_REPLY_KEY
static int
OFF_REPLY_KEY_EC
static int
PEER_SIZE
we show 16 bytes of the peer hash outside the elGamal block
-
Constructor Summary
Constructors Constructor Description BuildRequestRecord(I2PAppContext ctx, long receiveTunnelId, long nextTunnelId, Hash nextHop, long nextMsgId, boolean isInGateway, boolean isOutEndpoint, Properties options)
Populate this instance with data.BuildRequestRecord(I2PAppContext ctx, long receiveTunnelId, long nextTunnelId, Hash nextHop, long nextMsgId, SessionKey layerKey, SessionKey ivKey, SessionKey replyKey, byte[] iv, boolean isInGateway, boolean isOutEndpoint, Properties options)
Populate this instance with data.BuildRequestRecord(I2PAppContext ctx, long receiveTunnelId, Hash peer, long nextTunnelId, Hash nextHop, long nextMsgId, SessionKey layerKey, SessionKey ivKey, SessionKey replyKey, byte[] iv, boolean isInGateway, boolean isOutEndpoint)
Populate this instance with data.BuildRequestRecord(RouterContext ctx, PrivateKey ourKey, EncryptedBuildRecord encryptedRecord)
Decrypt the data from the specified record, writing the decrypted record into this instance's data buffer Caller MUST check that first 16 bytes of our hash matches first 16 bytes of encryptedRecord before calling this.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description EncryptedBuildRecord
encryptECIESRecord(RouterContext ctx, PublicKey toKey, Hash toPeer)
Encrypt the record to the specified peer.EncryptedBuildRecord
encryptRecord(I2PAppContext ctx, PublicKey toKey, Hash toPeer)
Encrypt the record to the specified peer.byte[]
getChaChaReplyAD()
Valid after calling encryptECIESRecord() or after the decrypting constructor with an ECIES private key.SessionKey
getChaChaReplyKey()
Valid after calling encryptECIESRecord() or after the decrypting constructor with an ECIES private key.byte[]
getData()
long
readExpiration()
The expiration in milliseconds from now.MessageWrapper.OneTimeSession
readGarlicKeys()
ECIES short OBEP record only.boolean
readIsInboundGateway()
The current hop is the inbound gateway.boolean
readIsOutboundEndpoint()
The current hop is the outbound endpoint.SessionKey
readIVKey()
Tunnel IV encryption key that the current hop should useint
readLayerEncryptionType()
ECIES short record only.SessionKey
readLayerKey()
Tunnel layer encryption key that the current hop should useHash
readNextIdentity()
Read the next hop from the record.long
readNextTunnelId()
What tunnel ID the next hop receives messages on.Properties
readOptions()
ECIES only.long
readReceiveTunnelId()
what tunnel ID should this receive messages onbyte[]
readReplyIV()
AES IV that should be used to encrypt the reply.SessionKey
readReplyKey()
AES Session key that should be used to encrypt the reply.long
readReplyMessageId()
What message ID should we send the request to the next hop with.long
readRequestTime()
For ElGamal, time that the request was sent (ms), truncated to the nearest hour.String
toString()
-
-
-
Field Detail
-
IV_SIZE
public static final int IV_SIZE
- See Also:
- Constant Field Values
-
PEER_SIZE
public static final int PEER_SIZE
we show 16 bytes of the peer hash outside the elGamal block- See Also:
- Constant Field Values
-
OFF_REPLY_KEY
public static final int OFF_REPLY_KEY
- See Also:
- Constant Field Values
-
OFF_REPLY_KEY_EC
public static final int OFF_REPLY_KEY_EC
- See Also:
- Constant Field Values
-
-
Constructor Detail
-
BuildRequestRecord
public BuildRequestRecord(RouterContext ctx, PrivateKey ourKey, EncryptedBuildRecord encryptedRecord) throws DataFormatException
Decrypt the data from the specified record, writing the decrypted record into this instance's data buffer Caller MUST check that first 16 bytes of our hash matches first 16 bytes of encryptedRecord before calling this. Not checked here. The ChaCha reply key and IV will be available via the getters after this call if ourKey is ECIES.- Throws:
DataFormatException
- on decrypt fail- Since:
- 0.9.48
-
BuildRequestRecord
public BuildRequestRecord(I2PAppContext ctx, long receiveTunnelId, Hash peer, long nextTunnelId, Hash nextHop, long nextMsgId, SessionKey layerKey, SessionKey ivKey, SessionKey replyKey, byte[] iv, boolean isInGateway, boolean isOutEndpoint)
Populate this instance with data. A new buffer is created to contain the data, with the necessary randomized padding. ElGamal only. ECIES constructor below.- Parameters:
receiveTunnelId
- tunnel the current hop will receive messages onpeer
- current hop's identity, unused, no read() methodnextTunnelId
- id for the next hop, or where we send the reply (if we are the outbound endpoint)nextHop
- next hop's identity, or where we send the reply (if we are the outbound endpoint)nextMsgId
- message ID to use when sending on to the next hop (or for the reply)layerKey
- tunnel layer key to be used by the peerivKey
- tunnel IV key to be used by the peerreplyKey
- key to be used when encrypting the reply to this build requestiv
- iv to be used when encrypting the reply to this build requestisInGateway
- are we the gateway of an inbound tunnel?isOutEndpoint
- are we the endpoint of an outbound tunnel?- Since:
- 0.9.18, was createRecord()
-
BuildRequestRecord
public BuildRequestRecord(I2PAppContext ctx, long receiveTunnelId, long nextTunnelId, Hash nextHop, long nextMsgId, SessionKey layerKey, SessionKey ivKey, SessionKey replyKey, byte[] iv, boolean isInGateway, boolean isOutEndpoint, Properties options)
Populate this instance with data. A new buffer is created to contain the data, with the necessary randomized padding. ECIES long record only. ElGamal constructor above.- Parameters:
receiveTunnelId
- tunnel the current hop will receive messages onnextTunnelId
- id for the next hop, or where we send the reply (if we are the outbound endpoint)nextHop
- next hop's identity, or where we send the reply (if we are the outbound endpoint)nextMsgId
- message ID to use when sending on to the next hop (or for the reply)layerKey
- tunnel layer key to be used by the peerivKey
- tunnel IV key to be used by the peerreplyKey
- key to be used when encrypting the reply to this build requestiv
- iv to be used when encrypting the reply to this build requestisInGateway
- are we the gateway of an inbound tunnel?isOutEndpoint
- are we the endpoint of an outbound tunnel?options
- 296 bytes max when serialized- Throws:
IllegalArgumentException
- if options too long- Since:
- 0.9.48
-
BuildRequestRecord
public BuildRequestRecord(I2PAppContext ctx, long receiveTunnelId, long nextTunnelId, Hash nextHop, long nextMsgId, boolean isInGateway, boolean isOutEndpoint, Properties options)
Populate this instance with data. A new buffer is created to contain the data, with the necessary randomized padding. ECIES short record only. ElGamal constructor above.- Parameters:
receiveTunnelId
- tunnel the current hop will receive messages onnextTunnelId
- id for the next hop, or where we send the reply (if we are the outbound endpoint)nextHop
- next hop's identity, or where we send the reply (if we are the outbound endpoint)nextMsgId
- message ID to use when sending on to the next hop (or for the reply)isInGateway
- are we the gateway of an inbound tunnel?isOutEndpoint
- are we the endpoint of an outbound tunnel?options
- 98 bytes max when serialized- Throws:
IllegalArgumentException
- if options too long- Since:
- 0.9.51
-
-
Method Detail
-
getData
public byte[] getData()
- Returns:
- 222 (ElG) or 464 (ECIES) bytes, non-null
-
readReceiveTunnelId
public long readReceiveTunnelId()
what tunnel ID should this receive messages on
-
readNextTunnelId
public long readNextTunnelId()
What tunnel ID the next hop receives messages on. If this is the outbound tunnel endpoint, this specifies the tunnel ID to which the reply should be sent.
-
readNextIdentity
public Hash readNextIdentity()
Read the next hop from the record. If this is the outbound tunnel endpoint, this specifies the gateway to which the reply should be sent.
-
readLayerKey
public SessionKey readLayerKey()
Tunnel layer encryption key that the current hop should use
-
readIVKey
public SessionKey readIVKey()
Tunnel IV encryption key that the current hop should use
-
readReplyKey
public SessionKey readReplyKey()
AES Session key that should be used to encrypt the reply. Not to be used for short ECIES records; use the ChaChaReplyKey instead.
-
readReplyIV
public byte[] readReplyIV()
AES IV that should be used to encrypt the reply. Not to be used for short ECIES records.- Returns:
- 16 bytes
-
readIsInboundGateway
public boolean readIsInboundGateway()
The current hop is the inbound gateway. If this is true, it means anyone can send messages to this tunnel, but if it is false, only the current predecessor can.
-
readIsOutboundEndpoint
public boolean readIsOutboundEndpoint()
The current hop is the outbound endpoint. If this is true, the next identity and next tunnel fields refer to where the reply should be sent.
-
readRequestTime
public long readRequestTime()
For ElGamal, time that the request was sent (ms), truncated to the nearest hour. For ECIES, time that the request was sent (ms), truncated to the nearest minute. This ignores leap seconds.
-
readReplyMessageId
public long readReplyMessageId()
What message ID should we send the request to the next hop with. If this is the outbound tunnel endpoint, this specifies the message ID with which the reply should be sent.
-
readExpiration
public long readExpiration()
The expiration in milliseconds from now.- Since:
- 0.9.48
-
readOptions
public Properties readOptions()
ECIES only.- Returns:
- null for ElGamal or on error
- Since:
- 0.9.48
-
readLayerEncryptionType
public int readLayerEncryptionType()
ECIES short record only.- Returns:
- 0 for ElGamal or ECIES long record
- Since:
- 0.9.51
-
readGarlicKeys
public MessageWrapper.OneTimeSession readGarlicKeys()
ECIES short OBEP record only.- Returns:
- null for ElGamal or ECIES long record or non-OBEP
- Since:
- 0.9.51
-
encryptRecord
public EncryptedBuildRecord encryptRecord(I2PAppContext ctx, PublicKey toKey, Hash toPeer)
Encrypt the record to the specified peer. The result is formatted as:bytes 0-15: truncated SHA-256 of the current hop's identity (the toPeer parameter) bytes 15-527: ElGamal-2048 encrypted block
ElGamal only- Returns:
- non-null
-
encryptECIESRecord
public EncryptedBuildRecord encryptECIESRecord(RouterContext ctx, PublicKey toKey, Hash toPeer)
Encrypt the record to the specified peer. ECIES only. The ChaCha reply key and IV will be available via the getters after this call. For short records, derived keys will be available via readLayerKey(), readIVKey(), and readGarlicKeys() after this call. See class javadocs for format. See proposals 152 and 157.- Returns:
- non-null
- Since:
- 0.9.48
-
getChaChaReplyKey
public SessionKey getChaChaReplyKey()
Valid after calling encryptECIESRecord() or after the decrypting constructor with an ECIES private key. See proposal 152.- Returns:
- null if no ECIES encrypt/decrypt operation was performed
- Since:
- 0.9.48
-
getChaChaReplyAD
public byte[] getChaChaReplyAD()
Valid after calling encryptECIESRecord() or after the decrypting constructor with an ECIES private key. See proposal 152.- Returns:
- null if no ECIES encrypt/decrypt operation was performed
- Since:
- 0.9.48
-
-