i2p-rs icon indicating copy to clipboard operation
i2p-rs copied to clipboard

"Invalid destination key" when trying to recover previously used session

Open a-0-dev opened this issue 2 years ago • 1 comments

I'm trying to store a session (or, its destination) for later reuse, so my b32 address doesn't change all the time. However, this fails with the error "Invalid destination key: " (yes, nothing follows after that colon), which means an invalid key error is returned by the router.

I wrote the following test to reproduce this issue:

#[test]
pub fn from_destination() {
    // Build an I2pListener with a "TRANSIENT" session
    let listener1 = I2pListenerBuilder::default()
        .with_options(SAMOptions::default())
        .build()
        .expect("Failed to build listener1");

    // Extract listener1's `destination`
    let listener1_dest = listener1
        .local_addr()
        .expect("Failed to get local address of listener1")
        .dest()
        .string();

    // Attempt to build a new I2pListener, recovering the previous session
    let listener2 = I2pListener{
        forward: StreamForward::with_session(&Session::from_destination(
            i2p::sam::DEFAULT_API, 
            &listener1_dest, 
            SAMOptions::default()).expect("Failed to create session for listener2")
        ).expect("Failed to create StreamForward for listener2")
    };

}

To be honest, I have no idea what's happening. I traced i2p-rs's code and the value of listener1_dest seems to be exactly what is replied by the router in Session::naming_lookup - thus should be a valid destination with bells and whistles.

This may be a router issue just as well as an i2p-rs issue...

a-0-dev avatar Nov 25 '23 15:11 a-0-dev

I found the issue and I'm close to submitting a PR for this. The wording in I2P documentation is ambiguous: "destination" can both be the public part of a node's key material, as described in the host name lookup documentation:

The $destination is the base 64 of the Destination, which is 516 or more base 64 characters (387 or more bytes in binary), depending on signature type.

...as well as the private part of a node's key material, as described in the Session Creation Response chapter of the documentation:

SESSION STATUS RESULT=OK DESTINATION=$privkey The $privkey is the base 64 of the concatenation of the Destination followed by the Private Key followed by the Signing Private Key, optionally followed by the Offline Signature, which is 663 or more bytes in binary and 884 or more bytes in base 64, depending on signature type. The binary format is specified in Private Key File.

So, before I submit a solution allowing a user of i2p-rs to extract the private key of a node from a Session: Should there be a name destinction (as in, e.g., always name the "private destination" private key or privkey while using "destanation" for the public part? I think that makes most sense, since a "destination" is usually something you send something to (hence, only have the public part of the key material), while the private part should be explicitly named private so i2p-rs users don't "accidentally" use it in an unsafe way.

Any thoughts on this?

a-0-dev avatar Dec 02 '23 11:12 a-0-dev