-
-
Notifications
You must be signed in to change notification settings - Fork 76
implement jwa algorithms #650
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
base: main
Are you sure you want to change the base?
Conversation
I've asked @soundofspace to do the initial reviews and guidance here. He'll come back to you. |
For changes in Places that need updating:
Also don't be afraid to look at the jwk rfc it's a decently sized one but it's split up in a lot of chapters and it also contains some examples And thanks for looking into this! |
rama-crypto/src/jose/jwa.rs
Outdated
} | ||
} | ||
|
||
impl TryFrom<JWA> for Box<&dyn RsaEncoding> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason to box this and not use &'static RsaSignatureEncoding
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RsaSignatureEncoding
is not exposed outside of the crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed that it was not exposed, in that case this is indeed a good approach
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw my i've been busy with my day job so this issue slipped my mind. I'll make a complete PR in a few days
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, no rush here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed that it was not exposed, in that case this is indeed a good approach
@soundofspace do you think that's a mistake of that crate? If so can you perhaps check with those crate authors to get that improved so we can do perhaps better here in future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GlenDC already did that a few hours ago
ba45afd
to
4377157
Compare
rama-crypto/src/jose/jwk.rs
Outdated
result.extend_from_slice(&final_len); | ||
result.extend_from_slice(&final_sequence); | ||
|
||
Ok(signature::UnparsedPublicKey::new(self.alg.try_into()?, result)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@soundofspace
The UnparsedPublicKey::new
takes trait objects of type VerificationAlgorithm
as argument. And JWA.alg
is of type dyn RsaEncoding
. So I couldn't figure out a way to convert our alg
field to that type. Any guidance would be appreciated.
rama-crypto/src/jose/jwk.rs
Outdated
.sign(*alg, self.rng(), data.as_bytes(), &mut sig) | ||
.context("sign protected data")?; | ||
// problem here | ||
Ok(sig.into()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sign method for RsaKeyPair
does not return the Signature
and the Signature
type does not expose it's new
method. So there is no way to construct that type. What should we do here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice progress, and thanks for looking into this!
rama-crypto/src/jose/jwa.rs
Outdated
} | ||
} | ||
|
||
impl TryFrom<JWA> for Box<&dyn RsaEncoding> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to &'static dyn RsaEncoding
so no allocations are needed
)), | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you also add these it should solve the issue you have with converting
impl TryFrom<JWA> for &'static dyn VerificationAlgorithm {
type Error = OpaqueError;
fn try_from(value: JWA) -> Result<Self, Self::Error> {
match value {
JWA::RS256 => Ok(&RSA_PKCS1_2048_8192_SHA256),
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And once that is is added, the logic from this one, should also be placed in there
impl TryFrom<JWA> for &'static EcdsaVerificationAlgorithm {
Something along these lines:
JWA::PS512 => Ok(&RSA_PSS_2048_8192_SHA512),
JWA::ES256 | JWA::ES384 ... => {
let signing_algo: &'static EcdsaSigningAlgorithm = value.try_into()?;
Ok(signing_algo.deref())
}
Otherwise there might be issues with try_into overlapping for the use case of verification
rama-crypto/src/jose/jwk.rs
Outdated
} | ||
|
||
impl Signer for RsaKey { | ||
type Signature = Signature; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Rsa signing this is a different signature
type Signature = Signature; | |
type Signature = Vec<u8>; |
So no need to do extra try_into in the sign method
4377157
to
e1c1ade
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice progress, some minor remarks but looks like it's almost ready
rama-crypto/src/jose/jwk.rs
Outdated
let n_der_encoded = utils::encode_integer(n_bytes); | ||
let e_der_encoded = utils::encode_integer(e_bytes); | ||
|
||
let mut rsa_public_key_sequence = Vec::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be possible to create all the vec's in this block with Vec::with_capacity
to prevent extra allocations and moves
rama-crypto/src/jose/jwk.rs
Outdated
let e_der_encoded = utils::encode_integer(e_bytes); | ||
|
||
let mut rsa_public_key_sequence = Vec::new(); | ||
rsa_public_key_sequence.extend_from_slice(&n_der_encoded); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you don't need these "original" vectors later you can you extend
instead which takes ownership and is more optimized
rama-crypto/src/jose/jwk.rs
Outdated
n: String::try_from(n.big_endian_without_leading_zero().to_vec()) | ||
.map_err(|e| OpaqueError::from_display(format!("{:?}", e)))?, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
n and e should be base64 encoded bytes which is not the same as String::try_from
, that one does utf8 encoding, instead use
BASE64_URL_SAFE_NO_PAD.encode(n)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also try to add some unit tests which should detect mistakes like this
} | ||
} | ||
|
||
pub struct RsaKey { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one will also have to import/exported in mod.rs
When you run linting/clippy/tests
just qa
or only linting/clippy without tests
just qq
It should also detect these things, same for unused imports
rama-crypto/src/jose/jwk.rs
Outdated
} | ||
|
||
/// Create pkcs8 der for the current [`RsaKeyPair`] | ||
pub fn pkcs8_der(&self) -> Result<(JWA, Pkcs8V1Der<'_>), OpaqueError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub fn pkcs8_der(&self) -> Result<(JWA, Pkcs8V1Der<'_>), OpaqueError> { | |
pub fn pkcs8_der(&self) -> Result<(JWA, Pkcs8V1Der<'static>), OpaqueError> { |
'static is more explicit here and its also what happens internally
rama-crypto/src/jose/jwk.rs
Outdated
|
||
fn sign(&self, data: &str) -> Result<Self::Signature, Self::Error> { | ||
let mut sig: Vec<u8> = Vec::new(); | ||
let alg = <&'static dyn RsaEncoding as TryFrom<JWA>>::try_from(self.alg)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let alg = <&'static dyn RsaEncoding as TryFrom<JWA>>::try_from(self.alg)?; | |
let alg = self.alg.try_into()?; |
Should be possible to just do this?
rama-crypto/src/jose/jwk.rs
Outdated
} | ||
} | ||
|
||
pub(super) fn encode_integer(mut bytes: Vec<u8>) -> Vec<u8> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add comment that this function should only be used for parsing JWK encoded rsa values. This function does not work for general asn1 encoding which is fine for this use case, but a comment should prevent other people from later extending this module and using this function for wrong use cases.
Some things that this function does not handle:
- empty bytes vec
- negative numbers
- assumes input is already in minimal format, which is not always the case in general asn 1
Again fine for this use case, but warrants a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you suggest me some resources where I could learn more about these specs?
8bfdb48
to
71b1713
Compare
71b1713
to
a839ce0
Compare
working on #621.
@GlenDC I've written the conversions in
rama-crypto/src/jose/jwa.rs
file. Let me know if they are correct. However, I'd like some guidance on what changes needs to be made in therama-crypto/src/jose/jwk.rs
file.