Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use arrays instead of slices and Vecs #33

Merged
merged 11 commits into from
Jun 22, 2022
Merged

Conversation

Xiretza
Copy link
Contributor

@Xiretza Xiretza commented May 22, 2022

There are several instance of &[u8] and Vec<u8> being used as argument types for data that is then fallibly converted into a fixed-size array inside the function. Using &[u8; N] or [u8; N] for the argument types instead means that many runtime length checks can be moved from the library's internals all the way out to the API boundary, and eventually removed entirely when the signatures of API functions are updated accordingly in a major update.

src/service.rs Outdated Show resolved Hide resolved
src/service.rs Outdated Show resolved Hide resolved
src/service.rs Outdated Show resolved Hide resolved
@tasn
Copy link
Member

tasn commented May 22, 2022

I don't remember why it was done this way. I suspect that maybe Rust had issues with arrays being passed like this? It was losing the size, or maybe it was just very very annoying to use it with fixed sizes because passing an array of a fixed size is a pain?

Does this make sense? Can you maybe try using this branch with libetebase and see whether this makes usage very annoying?

@Xiretza
Copy link
Contributor Author

Xiretza commented May 23, 2022

Ah, you think the FFI bindings will break? Well, this doesn't actually change any public APIs yet, so that shouldn't be a problem, but I'll test what happens if I do that.

Rust itself should be able to handle arrays just fine, the only possible concern is that passing huge arrays on the stack requires a bunch of copying, but since all the arrays here are <= 32 bytes, that shouldn't be a problem.

@Xiretza Xiretza force-pushed the internal-arrays branch from 6de23f9 to dfb5a2a Compare May 23, 2022 05:09
@tasn
Copy link
Member

tasn commented May 23, 2022

Ah, you think the FFI bindings will break? Well, this doesn't actually change any public APIs yet, so that shouldn't be a problem, but I'll test what happens if I do that.

No, libetebase wraps around this lib. I just remember it was very painful to e.g. take a Vec and pass it to a sized array (I think that was the issue). So e.g.:

fn foo(bar: &[u8; 32]) {
    // ...
}

let a: Vec<u8> = ...;
# Calling foo with a was a pain.

I think that was the issue, but I don't remember.

What I was saying though: let's also change libetebase to use this updated API and see whether it's very painful, or whether it's easy to use this new API.

Rust itself should be able to handle arrays just fine, the only possible concern is that passing huge arrays on the stack requires a bunch of copying, but since all the arrays here are <= 32 bytes, that shouldn't be a problem.

Yeah, that's not what I meant.

@Xiretza
Copy link
Contributor Author

Xiretza commented May 23, 2022

fn foo(bar: &[u8; 32]) {
    // ...
}

let a: Vec<u8> = ...;
# Calling foo with a was a pain.

That should just be foo(a.as_slice().try_into()?);. If the data is arbitrary user input, the length check still needs to happen somewhere, and I think it's better to move it as close to the API surface as possible (and eventually outside it) so the library core itself doesn't have to bother with them.

What I was saying though: let's also change libetebase to use this updated API and see whether it's very painful, or whether it's easy to use this new API.

There is nothing to change in libetebase yet. This PR does not change the public API. Eventually, the public API can be changed to use arrays so that some length checks inside the library can be moved to its consumers - I quickly did that for testing, the libetebase changes are pretty contained: Xiretza/libetebase@37eabc1

@tasn
Copy link
Member

tasn commented May 23, 2022

Oh, I didn't realize it didn't change the public API. OK, please rebase over main and I'll take a look.

@Xiretza Xiretza force-pushed the internal-arrays branch from dfb5a2a to 5d9f825 Compare May 23, 2022 10:20
@Xiretza
Copy link
Contributor Author

Xiretza commented Jun 21, 2022

Hi! It's been a month, just want to make sure this hasn't fallen through the cracks. I don't want to be pushy, but I'd like to get a couple small internal cleanups like this out of the way before I tackle more useful things such as #27.

@tasn
Copy link
Member

tasn commented Jun 21, 2022

I don't get notifications unless your re-request a review. So I didn't know you rebased. :)

Looking now...

Copy link
Member

@tasn tasn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, though there are a few open questions.

src/crypto.rs Show resolved Hide resolved
src/service.rs Outdated Show resolved Hide resolved
src/service.rs Outdated Show resolved Hide resolved
src/service.rs Outdated
Comment on lines 189 to 205
// Use only first 16 bytes of salt - previous versions generated a 32-byte salt during
// signup, but only used the first 16 bytes
let salt = login_challenge
.salt
.get(..SALT_LENGTH)
.ok_or(Error::Encryption(
"Salt obtained from login challenge too short: expected at least 16 bytes",
))?
.try_into()
.unwrap();
let main_key = derive_key(&salt, password)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's probably fine, though it's harmless to keep it at 32 and much less scary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't actually a change in functionality, the check has just been moved out of derive_key() (and now doesn't panic anymore if the received hash is shorter than 16 bytes). I've adjusted the comment though.

src/service.rs Outdated Show resolved Hide resolved
src/service.rs Show resolved Hide resolved
src/service.rs Outdated Show resolved Hide resolved
@Xiretza
Copy link
Contributor Author

Xiretza commented Jun 21, 2022

I don't get notifications unless your re-request a review. So I didn't know you rebased. :)

Doh! Good to know for the future.

@Xiretza Xiretza requested a review from tasn June 21, 2022 17:51
@tasn tasn merged commit be0cf43 into etesync:master Jun 22, 2022
@tasn
Copy link
Member

tasn commented Jun 22, 2022

Code looks much much better, thanks and gj!

@Xiretza Xiretza deleted the internal-arrays branch June 22, 2022 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants