Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
855 stars 233 forks source link

Support load openssh oneline format public key #277

Open AndrewTsao opened 1 year ago

AndrewTsao commented 1 year ago

What would you like to see added?

jwt::algorithm::rs256 support load openssh oneline format public key.

Additional Context

  std::string rsa_pub_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCPgCi68jXsRX/4bgVFBfv4vyuK0vno13FKqKmBF12YgYUQalv6Km2N6yh2llgiDRKEo/DLUvKDSSonzIZeQ396lAwqM1hEdQ9py8bUUMeX5RjUSO24TRaJhuw62sRwSxDdwBjo6F0fmugLG4tmK9ulbSpHSRQcwKGt701DmMGhyQ==";
  std::cout << "PUB KEY:\n" << rsa_pub_key << std::endl;

    try {
    auto verify = jwt::verify().allow_algorithm(jwt::algorithm::rs256(rsa_pub_key, "", "", ""));
    auto decoded = jwt::decode(token);
        verify.verify(decoded);
    for (auto& e : decoded.get_header_json())
      std::cout << e.first << " = " << e.second << std::endl;
    for (auto& e : decoded.get_payload_json())
      std::cout << e.first << " = " << e.second << std::endl;
    } catch (const std::exception& ex) {
        std::cout << "verify failed." << ex.what() << std::endl;
    return 1;
    }

throw an exception, "failed to load key: bio read failed".

Thalhammer commented 1 year ago

OpenSSL can't directly parse OpenSSH public keys because OpenSSH uses its own unique format. The format on the other hand seems to be fairly simple to parse and I think we should already have everything needed to do so, so the general idea would be as follows:

- Do a starts_with to check if it is a openssh key
- Split at the spaces and throw away everything except the middle part
- Base64 decode it
   - The contained data consists of a variable number of length prefixes blobs
   - Parse the 2. and 3. part as a OpenSSL bignum (they represent e&n)
   - Use RSA_set0_key to build a key from it

Some issues I see with this:

Generally I like the idea.

AndrewTsao commented 1 year ago

Thank you for your anwser.

Thalhammer commented 1 year ago

Not sooo fast 😄 I said I like the idea.

@prince-chrismc What do you think about this, should we include this ? It seems definitely implementable to me.

prince-chrismc commented 1 year ago

It's a good idea, I am not sure how other servers or clients would work though 🤔 if we can transform the format in RSA modulus and exponent than it's a good value add feature... but probably erroneous, I suspect people are just using a key they already had instead of creating proper keys.

There's a reason ssh keys are not supported by tls and I think the jwt separation also makes sense.