1111#include < openssl/pem.h>
1212#include < openssl/ec.h>
1313#include < openssl/err.h>
14+ #include < openssl/bn.h>
15+ #include < openssl/rsa.h>
16+
17+ #include " rgw/rgw_b64.h"
1418
1519// If openssl version less than 1.1
1620#if OPENSSL_VERSION_NUMBER < 269484032
@@ -233,6 +237,17 @@ namespace jwt {
233237 } else
234238 throw rsa_exception (" at least one of public or private key need to be present" );
235239 }
240+
241+ rsa (const EVP_MD*(*md)(), const std::string& name) : md(md), alg_name(name)
242+ {}
243+
244+ void setModulusExponentCalcPublicKey (const std::string& modulus, const std::string& exponent)
245+ {
246+ this ->modulus = modulus;
247+ this ->exponent = exponent;
248+ calculatePublicKey ();
249+ }
250+
236251 /* *
237252 * Sign jwt data
238253 * \param data The data to sign
@@ -296,8 +311,43 @@ namespace jwt {
296311 std::shared_ptr<EVP_PKEY> pkey;
297312 // / Hash generator
298313 const EVP_MD*(*md)();
314+ // / Modulus
315+ std::string modulus;
316+ // / Exponent
317+ std::string exponent;
299318 // / Algorithmname
300319 const std::string alg_name;
320+
321+ void calculatePublicKey ()
322+ {
323+ std::string n_str = base64_decode_url (modulus);
324+ std::string e_str = base64_decode_url (exponent);
325+ unsigned char * u_n = (unsigned char *)n_str.c_str ();
326+ unsigned char * u_e = (unsigned char *)e_str.c_str ();
327+ BIGNUM *n = BN_bin2bn (u_n, n_str.size (), NULL );
328+ BIGNUM *e = BN_bin2bn (u_e, e_str.size (), NULL );
329+
330+ if (e && n) {
331+ EVP_PKEY* pRsaKey = EVP_PKEY_new ();
332+ RSA* rsa = RSA_new ();
333+ RSA_set0_key (rsa, n, e, nullptr );
334+ EVP_PKEY_assign_RSA (pRsaKey, rsa);
335+ std::shared_ptr<EVP_PKEY> p (pRsaKey, EVP_PKEY_free);
336+ pkey = p;
337+ } else {
338+ if (n) BN_free (n);
339+ if (e) BN_free (e);
340+ throw rsa_exception (" Invalid encoding for modulus or exponent\n " );
341+ }
342+ }
343+
344+ std::string base64_decode_url (const std::string& str) const {
345+ std::string s = " ====" ;
346+ std::string padded_str = str.length () % 4 == 0 ? str : str + s.substr (0 , str.length () % 4 );
347+ std::replace (padded_str.begin (), padded_str.end (), ' _' , ' /' );
348+ std::replace (padded_str.begin (), padded_str.end (), ' -' , ' +' );
349+ return rgw::from_base64 (padded_str);
350+ }
301351 };
302352 /* *
303353 * Base class for ECDSA family of algorithms
@@ -629,6 +679,15 @@ namespace jwt {
629679 explicit rs256 (const std::string& public_key, const std::string& private_key = " " , const std::string& public_key_password = " " , const std::string& private_key_password = " " )
630680 : rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha256, " RS256" )
631681 {}
682+
683+ rs256 () : rsa(EVP_sha256, " RS256" )
684+ {}
685+
686+ rs256& setModulusAndExponent (const std::string& modulus, const std::string& exponent)
687+ {
688+ rsa::setModulusExponentCalcPublicKey (modulus, exponent);
689+ return *this ;
690+ }
632691 };
633692 /* *
634693 * RS384 algorithm
@@ -644,6 +703,15 @@ namespace jwt {
644703 explicit rs384 (const std::string& public_key, const std::string& private_key = " " , const std::string& public_key_password = " " , const std::string& private_key_password = " " )
645704 : rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha384, " RS384" )
646705 {}
706+
707+ rs384 () : rsa(EVP_sha384, " RS384" )
708+ {}
709+
710+ rs384& setModulusAndExponent (const std::string& modulus, const std::string& exponent)
711+ {
712+ rsa::setModulusExponentCalcPublicKey (modulus, exponent);
713+ return *this ;
714+ }
647715 };
648716 /* *
649717 * RS512 algorithm
@@ -659,6 +727,15 @@ namespace jwt {
659727 explicit rs512 (const std::string& public_key, const std::string& private_key = " " , const std::string& public_key_password = " " , const std::string& private_key_password = " " )
660728 : rsa(public_key, private_key, public_key_password, private_key_password, EVP_sha512, " RS512" )
661729 {}
730+
731+ rs512 () : rsa(EVP_sha512, " RS512" )
732+ {}
733+
734+ rs512& setModulusAndExponent (const std::string& modulus, const std::string& exponent)
735+ {
736+ rsa::setModulusExponentCalcPublicKey (modulus, exponent);
737+ return *this ;
738+ }
662739 };
663740 /* *
664741 * ES256 algorithm
0 commit comments