jsonwebtoken icon indicating copy to clipboard operation
jsonwebtoken copied to clipboard

Possibility of a `from_pem` constructor for Decoding and Encoding keys

Open krishna-kashyap opened this issue 2 years ago • 4 comments

I was looking at using the from PEM options for the Decoding key and seems like despite of having all the information from the parsing at the time of creating PemEncodingKey, the methods exposed need the user to explicitly specify the type of the key which is then checked on a match and and error emitted.

So could we have a from_pem constructor which in turn does a match and creates the encoding and decoding keys?

If it makes sense, I'd be interested in adding it

krishna-kashyap avatar Feb 09 '23 13:02 krishna-kashyap

I think the current situation is fine, can you write some pseudo-code on how it would look with what you're proposing?

Keats avatar Feb 09 '23 13:02 Keats

Something like this? However this needed changing a few permissions from the other module. This is possibly not the best approach, better one would actually be to possibly expose the type and content of the key for the decoding/encoding keys in the decoder. More like as_private_key and as_public_key which provides the information about the Family and the Content

+    /// If you are loading a public key in a PEM format, use this.
+    #[cfg(feature = "use_pem")]
+    pub fn from_pem(key: &[u8]) -> Result<Self> {
+        let pem_key = PemEncodedKey::new(key)?;
+        match pem_key.pem_type {
+            PemType::EcPublic => {
+                Ok(DecodingKey {
+                    family: AlgorithmFamily::Ec,
+                    kind: DecodingKeyKind::SecretOrDer(pem_key.as_ec_public_key().unwrap().to_vec()),
+                })
+            },
+            PemType::EdPublic => {
+                Ok(DecodingKey {
+                        family: AlgorithmFamily::Ed,
+                        kind: DecodingKeyKind::SecretOrDer(pem_key.as_ed_public_key().unwrap().to_vec()),
+                    })
+                },
+            PemType::RsaPublic => {
+                Ok(DecodingKey {
+                        family: AlgorithmFamily::Rsa,
+                        kind: DecodingKeyKind::SecretOrDer(pem_key.as_rsa_key().unwrap().to_vec()),
+                    })

...skipping 1 line
+
+            _ => Err(ErrorKind::InvalidKeyFormat.into()),
+        }
+    }
+

krishna-kashyap avatar Feb 12 '23 11:02 krishna-kashyap

I think I prefer seeing the expected alg type in the user code.

Keats avatar Feb 13 '23 14:02 Keats

However I see this more like from_jwt instead of expecting user to instead call the from components themselves by actually parsing the key component from the token when they have a PEM key instead of the standard components.

krishna-kashyap avatar Feb 13 '23 15:02 krishna-kashyap