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

Add PEM decoding support #106

Merged
merged 6 commits into from
Nov 3, 2019
Merged

Add PEM decoding support #106

merged 6 commits into from
Nov 3, 2019

Conversation

LeviSchuck
Copy link
Contributor

This adds a new top level function decode_pem, and a subsequent function as_key on the result type for use with sign and verify.

This contributes to #76 and #77
However it does not include X.509 certificate support.

I have an idea on how to do that but this should handle many cases that users want as PEM files are the common output from openssl

It supports both PKCS#1 and PKCS#8 RSA keys, it supports PKCS#8 EC keys, however it doesn't assert that the curve ID but within JWT contexts the curve is predefined by the spec.

Copy link
Owner

@Keats Keats left a comment

Choose a reason for hiding this comment

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

That looks good!
I will probably change the API to make it easy for users but all the effort it very appreciated.

How did you generate the PEM keys? I will add all the defaut ones from jwt.io later on to ensure everything is fine.

Cargo.toml Outdated Show resolved Hide resolved
README.md Outdated
you can run the following commands to obtain the DER keys from PKCS#1 (ie with `BEGIN RSA PUBLIC KEY`) .pem.
`jsonwebtoken` can read DER and PEM encoded keys.

If you want to use DER encoded keys review the following.
Copy link
Owner

Choose a reason for hiding this comment

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

this sentence seems like it's missing stuff?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the readme a little.

@LeviSchuck
Copy link
Contributor Author

How did you generate the PEM keys? I will add all the defaut ones from jwt.io later on to ensure everything is fine.

All of the key data is derived from what was already in the repo. I renamed the private_rsa_key.pem to its corresponding _pkcs8 type. I've gone through my zsh history for exact answers.

The PKCS#1 keys are the base64 encoded .der keys already in the repository with the corresponding PEM tag PRIVATE RSA KEY or PUBLIC RSA KEY.

The PKCS#8 RSA public key was created from the private key with an openssl command.
openssl pkcs8 -topk8 -in private_rsa_key.pem -out private_rsa_key_pkcs8.pem -nocrypt

The PKCS#8 EC private key was created from the .pk8 file already in the repository.
base64 public_ecdsa_key.pk8 | awk '{gsub(/.{64}/,"&\n")}1' > public_ecdsa_key.pem followed by manually adding the PEM Tagging -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- around the existing file.

And the public key was then derived from that
openssl ec -in private_ecdsa_key.pem -pubout -out public_ecdsa_key.pem

@LeviSchuck
Copy link
Contributor Author

I will probably change the API to make it easy for users but all the effort it very appreciated.

Sure, I'm not set on how the API came out, though I struggled with lifetimes. There's the challenges I experienced that resulted in this API.

  1. PEM Decoding allocates its own Vec<u8> for the base64 contents.
  2. ASN1 Parsing references the slice made from the Vec<u8> above
  3. The Key::(Der|Pkcs8) enums use a slice reference, which may either be directly from the PEM decoded contents or from a subsection as selected from the ASN1 parsing.

This is the first real rust and opensource contribution I've made so I appreciate the critique you give.

@LeviSchuck
Copy link
Contributor Author

Your PR seems to have landed Keats, and is now on crate
jcreekmore/pem-rs#19
https://crates.io/crates/pem

I'll update the PR by bumping the pem version

@Keats
Copy link
Owner

Keats commented Nov 1, 2019

Thanks!

This is the first real rust and opensource contribution I've made so I appreciate the critique you give.

I'll give a better review then but that will have to wait the weekend/next week.

@Keats Keats changed the base branch from next to pem-handling November 2, 2019 11:08
Copy link
Owner

@Keats Keats left a comment

Choose a reason for hiding this comment

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

Not much to say, it's pretty good!
Don't worry about fixing them, the API might change significantly

enum Classification {
EC,
RSA,
}
Copy link
Owner

Choose a reason for hiding this comment

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

I would put all of those at the top above the struct.

}

#[derive(Debug)]
#[derive(PartialEq)]
Copy link
Owner

Choose a reason for hiding this comment

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

You can (and should) put those derive in a single command: #[derive(Debug, PartialEq)]

}
}
_ => {
println!("Ignoring {:?}", asn1_entry);
Copy link
Owner

Choose a reason for hiding this comment

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

you can remove that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh yes definitely, that was a debugging helper.

}
simple_asn1::ASN1Block::ObjectIdentifier(_, oid) => {
if oid == ec_public_key_oid {
return Option::Some(Classification::EC);
Copy link
Owner

Choose a reason for hiding this comment

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

No need for Option::

}
}
}
return Option::default();
Copy link
Owner

Choose a reason for hiding this comment

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

you can replace that line by None

@Keats
Copy link
Owner

Keats commented Nov 2, 2019

Note: I'll merge it in the pem-handling branch first to experiment with the API and to make it easy for you to follow all the changes/give feedback.

@LeviSchuck
Copy link
Contributor Author

I look forward to it.

@Keats Keats merged commit 5718982 into Keats:pem-handling Nov 3, 2019
Keats added a commit that referenced this pull request Nov 15, 2019
JadedBlueEyes referenced this pull request in JadedBlueEyes/jsonwebtoken Apr 13, 2023
* Add PEM support with pem and simple_asn1. Documentation TODO

* Make pkcs1 and pkcs8 versions of the RSA key, confirm they pass tests.

* Add documentation, simplify

* Update readme

* Bump pem version

* Remove extra print
JadedBlueEyes referenced this pull request in JadedBlueEyes/jsonwebtoken Apr 13, 2023
Add PEM decoding support (#106)
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