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

Compatiblity layer with RustCrypto #192

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

baloo
Copy link
Contributor

@baloo baloo commented Nov 23, 2023

This is another take on #158

The purpose is to bring a compatibility layer with rustcrypto and use the tools developed there (x509 signing, pkcs7/CMS, ocsp, ...) with a pkcs#11-backed HSM

@baloo baloo force-pushed the baloo/rustcrypto/init branch 4 times, most recently from a68557d to 230120d Compare November 25, 2023 07:17
@ionut-arm
Copy link
Member

ionut-arm commented Nov 25, 2023

Amazing amount of work 🤯 thank you for the patch, I'll do a deep-dive when I get a bit of time.

One thing I'm wondering is if it makes more sense to have the extra functionality as a new crate, or as a module in the existing crate. We have something similar in tss-esapi with the abstractions module - not really sure which way is better, tbh, they both have advantages.

EDIT: if we keep it as a separate crate maybe we can frame it as a generic abstractions crate as well - if we want to implement other nice-to-have functionality in the future, we can just chuck it in the same one, as a separate mod.

@baloo
Copy link
Contributor Author

baloo commented Nov 25, 2023

I don't really have an opinion whether to make it a module (behind a feature flag) or an additional crate. What I know is that this is going to end up pulling a chunky part of rust-crypto and that dependency management is going to be tedious.
I tend to believe this is going to be slightly easier with an external crate, but I'm fine either way.

I do intend to bring a similar abstraction over to tss-esapi.

For the background story of this effort, nixos folks (this includes @RaitoBezarius who chimed in earlier) are doing secureboot work, and intend to use rust to sign build artifacts (with both HSM and TPM, depending on the use-case).
We have a PE signer (https://github.com/RaitoBezarius/goblin-signing) that consumes a signatures::Signer.
I (/me pulls the professional hat) am deploying a similar effort at work (secureboot efforts as well as PKI work).

I do intend to continue supporting this in the foreseeable future.

@baloo baloo force-pushed the baloo/rustcrypto/init branch 2 times, most recently from b7a3961 to b00e7c5 Compare November 26, 2023 22:28
@baloo baloo force-pushed the baloo/rustcrypto/init branch 2 times, most recently from 066d6fa to 2972f78 Compare December 1, 2023 23:35
@RaitoBezarius
Copy link

Happy new year! Anything we can do on our side to make this PR gets in a nice state for merge? :)

Copy link
Member

@ionut-arm ionut-arm left a comment

Choose a reason for hiding this comment

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

Thank you for the patch! I've read throug the non-test code and it seems like a great step forward to me. Left a few comments below, but overall I'd be happy to merge.

Regarding the massive delay - if either of you would be willing to join us on the Slack channel, please ping me directly there and I'll make time to look at changes/issues/etc. Unfortunately it's all too easy for things to slip between cracks 😞

cryptoki-rustcrypto/src/lib.rs Show resolved Hide resolved
cryptoki-rustcrypto/src/ecdsa.rs Show resolved Hide resolved
/// [`Rng`] is a PKCS#11-backed CSPRNG.
pub struct Rng<S: SessionLike>(S);

// TODO(baloo): check for CKF_RNG bit flag (CK_TOKEN_INFO struct -> flags)
Copy link
Member

Choose a reason for hiding this comment

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

Was this resolved, or will it result in a new issue once this is merged?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I'll need to make an API change to session to get back the Pkcs11 object and get_token_info on it.

Comment on lines +40 to +48
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.try_fill_bytes(dest)
.expect("Cryptoki provider failed to generate random");
}
Copy link
Member

Choose a reason for hiding this comment

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

I take it there's no way to not implement this and have the user always deal with the potential error. That's quite unfortunate. Maybe a comment on this method would be good to warn of a potential panic?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep. I think the "panic warninig" is part of the documentation of the interface:

This method should guarantee that dest is entirely filled with new data, and may panic if this is impossible (e.g. reading past the end of a file that is being used as the source of randomness).

Source: https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html#tymethod.fill_bytes

Copy link
Contributor Author

@baloo baloo Feb 24, 2024

Choose a reason for hiding this comment

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

I added a documentation for that panic on our Rng object.

Comment on lines +66 to +78
pub enum Error {
#[error("Cryptoki error: {0}")]
Cryptoki(#[from] cryptoki::error::Error),

#[error("Private key missing attribute: {0}")]
MissingAttribute(AttributeType),

#[error("RSA error: {0}")]
Rsa(#[from] rsa::Error),

#[error("Key not found")]
MissingKey,
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious - why have a different error struct per module? Seems like it could add some headaches if someone wants to use multiple crypto primitives in the same file, they'd have to import and rename them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree. One Error type should be sufficient. ( ™️ )

(But seriously, it's not such a big crate to need so many Errors).

Copy link
Contributor Author

@baloo baloo Feb 24, 2024

Choose a reason for hiding this comment

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

I go back and forth between "errors should be the most precise" and "dyn Error is enough for everyone". Looks like that day was the former.

cryptoki-rustcrypto/src/ecdsa.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@wiktor-k wiktor-k left a comment

Choose a reason for hiding this comment

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

It's a great idea and thanks for working on it... I expect to be in need of this kind of crate in the future so... thanks for your time and work! 🙏

cryptoki-rustcrypto/src/lib.rs Show resolved Hide resolved
Comment on lines +40 to +48
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.try_fill_bytes(dest)
.expect("Cryptoki provider failed to generate random");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep. I think the "panic warninig" is part of the documentation of the interface:

This method should guarantee that dest is entirely filled with new data, and may panic if this is impossible (e.g. reading past the end of a file that is being used as the source of randomness).

Source: https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html#tymethod.fill_bytes

Comment on lines +66 to +78
pub enum Error {
#[error("Cryptoki error: {0}")]
Cryptoki(#[from] cryptoki::error::Error),

#[error("Private key missing attribute: {0}")]
MissingAttribute(AttributeType),

#[error("RSA error: {0}")]
Rsa(#[from] rsa::Error),

#[error("Key not found")]
MissingKey,
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree. One Error type should be sufficient. ( ™️ )

(But seriously, it's not such a big crate to need so many Errors).

Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
Signed-off-by: Arthur Gautier <baloo@superbaloo.net>
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.

4 participants