Skip to content
New issue

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

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

Already on GitHub? # to your account

Seed initial client #1

Merged
merged 1 commit into from
Mar 24, 2020
Merged

Seed initial client #1

merged 1 commit into from
Mar 24, 2020

Conversation

ionut-arm
Copy link
Member

This commit adds the initial version of the Parsec Rust client.

Signed-off-by: Ionut Mihalcea ionut.mihalcea@arm.com

This version of the client is not finished and requires a lot of changes for it to be usable/production-ready. Some of the things that are not done well and will be improved are:

  • documentation is minimal and needs to be expanded
  • tests should be implemented, either with a "mock service" or with the real Parsec service
  • there are still unsafe uses of unwrap, expect ...
  • there is no configuration of the parameters used
  • the API of the client was not designed to match any existing "ergonomic design" crypto APIs from the Rust ecosystem
  • potentially others - if you find this kind of issues that are more structural than syntactic/aesthetic, please add a [FYI] comment and raise an issue for later fixing

Recommended review order:

  • all the markdown/legal files
  • src/core/request_handler.rs
  • src/core/mod.rs
  • src/auth.rs
  • src/lib.rs
  • CI-related files

@ionut-arm ionut-arm added the enhancement New feature or request label Mar 20, 2020
@ionut-arm ionut-arm requested review from hug-dev and anta5010 March 20, 2020 11:34
@ionut-arm ionut-arm self-assigned this Mar 20, 2020
test/ci.sh Outdated
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
Copy link
Member Author

Choose a reason for hiding this comment

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

The parent folder of this will be renamed to tests to fix the CI workflows

Copy link
Member

@hug-dev hug-dev left a comment

Choose a reason for hiding this comment

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

Thanks for fleshing out the Rust client!
I like the idea of the Core client: a basic client that allows to send all possible operations with all parameters, with no "intelligence". That will be the basis for more advanced, abstracted modules. I propose, to make it easier to scale, to put this core client in his own module.

README.md Outdated Show resolved Hide resolved
src/auth.rs Outdated

/// Authentication token
#[derive(Clone, Debug)]
pub enum AuthToken {
Copy link
Member

Choose a reason for hiding this comment

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

To match documentation I would name this structure AuthType (or just Authentication) with variants: None, Direct { application_identity: String } and in the future maybe Token(...)

Copy link
Member Author

Choose a reason for hiding this comment

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

Indeed, didn't realise Token was just the JWT stuff

Copy link
Member Author

@ionut-arm ionut-arm Mar 23, 2020

Choose a reason for hiding this comment

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

Reckon we can name it ApplicationIdentity? I think in the direct case, the String could be called name instead

Copy link
Member

Choose a reason for hiding this comment

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

For me the ApplicationIdentity is only the identity of the application in clear text, the name used for namespacing the key names for example. For me, it is directly passed for Direct authentication type and included in the JWT token. This type seems to represent that particular authentication field type and its content?

Copy link
Member Author

Choose a reason for hiding this comment

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

Cool, will name the field inside DirectAuthentication as identity (documentation names it that too), but I'll try and find a name for this struct - Authentication isn't really correct

Copy link
Member Author

Choose a reason for hiding this comment

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

Settled on AuthenticationFactor as this seems to be the term for the information provided when authenticating something.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ergh, or maybe not 😕

src/core/request_handler.rs Outdated Show resolved Hide resolved
Comment on lines 40 to 45
stream
.set_read_timeout(self.timeout)
.expect("Failed to set read timeout for stream");
stream
.set_write_timeout(self.timeout)
.expect("Failed to set write timeout for stream");
Copy link
Member

Choose a reason for hiding this comment

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

Maybe the socket connection + the timeout setting can be done only once when building the RequestHandler? So that after it is faster so send requests.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not really, this is a problem we encountered last time - one stream = one E2E connection. Once the response is sent, the service closes its side and writing to the stream results in a broken pipe error.

Copy link
Member Author

Choose a reason for hiding this comment

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

(Also not closing the connection on the service side would probably be a memory leak)

Copy link
Member

Choose a reason for hiding this comment

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

Oh yes sorry you are right! I forgot about that one 😃

src/lib.rs Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated
}

/// generate key
pub fn generate_key(
Copy link
Member

Choose a reason for hiding this comment

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

Should we prefix them with psa_ as well?

Copy link
Member Author

Choose a reason for hiding this comment

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

Don't know what to say. Maybe at this lowest layer it could make sense, but I don't think clients would be particularly interested in the fact that this operation comes from the PSA spec. Might be wrong... I think my point is that this could(/should?) be an abstraction over the things offered by the service. Not sure how it would be settled for a client that supports some provider-specific version of, say, generate_key

Copy link
Member

Choose a reason for hiding this comment

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

Maybe at this lowest layer it could make sense
That is what I was thinking as well: that this low layer (the "core") could be the dumb translation, in client side, of all our operation with all parameters. With that in mind, it would make sense to me to have the psa_ prefix, as those are PsaXXX operations.

I agree that once on higher abstraction layers, we should probably drop the prefix as it would make less sense.

src/lib.rs Outdated
///
/// The client exposes low-level functionality for using the Parsec service
#[derive(Debug)]
pub struct CoreClient {
Copy link
Member

Choose a reason for hiding this comment

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

As the name of the structure suggests, I feel like it would belong better in the core module. Maybe we should leave src/lib.rs for re-exports, have core for exposing all our operations will all parameters so that it will be easier to expand with another module later which does more of smart-defaulting.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd be ok with not implementing anything in lib.rs and just re-exporting from here

src/core/mod.rs Outdated
/// OperationHandler structure to send a `NativeOperation` and get a `NativeResult`.
#[derive(Derivative)]
#[derivative(Debug)]
pub struct OperationHandler {
Copy link
Member

Choose a reason for hiding this comment

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

If the Core operations currently in src/lib.rs went here, this file could go to src/core/operation_handler.rs for example.

Copy link
Member Author

Choose a reason for hiding this comment

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

Makes sense!

Copy link
Member

@hug-dev hug-dev left a comment

Choose a reason for hiding this comment

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

Sorry for next round of comments. Maybe it would have been easier to sketch the design before and discuss on it 😕

src/auth.rs Outdated

/// Authentication token
#[derive(Clone, Debug)]
pub enum AuthToken {
Copy link
Member

Choose a reason for hiding this comment

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

For me the ApplicationIdentity is only the identity of the application in clear text, the name used for namespacing the key names for example. For me, it is directly passed for Direct authentication type and included in the JWT token. This type seems to represent that particular authentication field type and its content?

src/core/request_handler.rs Outdated Show resolved Hide resolved
Comment on lines 40 to 45
stream
.set_read_timeout(self.timeout)
.expect("Failed to set read timeout for stream");
stream
.set_write_timeout(self.timeout)
.expect("Failed to set write timeout for stream");
Copy link
Member

Choose a reason for hiding this comment

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

Oh yes sorry you are right! I forgot about that one 😃

src/lib.rs Outdated
}

/// generate key
pub fn generate_key(
Copy link
Member

Choose a reason for hiding this comment

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

Maybe at this lowest layer it could make sense
That is what I was thinking as well: that this low layer (the "core") could be the dumb translation, in client side, of all our operation with all parameters. With that in mind, it would make sense to me to have the psa_ prefix, as those are PsaXXX operations.

I agree that once on higher abstraction layers, we should probably drop the prefix as it would make less sense.

This commit adds the initial version of the Parsec Rust client.

Signed-off-by: Ionut Mihalcea <ionut.mihalcea@arm.com>
@ionut-arm
Copy link
Member Author

I think most points raised should be covered, apart from the naming of authentication-related stuff.

Copy link
Member

@hug-dev hug-dev left a comment

Choose a reason for hiding this comment

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

Thanks for addressing the comments!

@ionut-arm ionut-arm merged commit 26d08ee into parallaxsecond:master Mar 24, 2020
@ionut-arm ionut-arm deleted the init branch March 24, 2020 09:42
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants