1010#include < openssl/bn.h>
1111#include < openssl/ec.h>
1212
13+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
14+ #include < openssl/evp.h>
15+ #include < openssl/param_build.h>
16+ #endif
17+ #define EC_NAME NID_X9_62_prime256v1
18+
1319#include " scitokens_internal.h"
1420
1521using namespace scitokens ;
@@ -243,8 +249,60 @@ std::string
243249es256_from_coords (const std::string &x_str, const std::string &y_str) {
244250 auto x_decode = b64url_decode_nopadding (x_str);
245251 auto y_decode = b64url_decode_nopadding (y_str);
252+ std::unique_ptr<BIO, decltype (&BIO_free_all)> pubkey_bio (BIO_new (BIO_s_mem ()), BIO_free_all);
253+ std::unique_ptr<BIGNUM, decltype (&BN_free)> x_bignum (BN_bin2bn (reinterpret_cast <const unsigned char *>(x_decode.c_str ()), x_decode.size (), nullptr ), BN_free);
254+ std::unique_ptr<BIGNUM, decltype (&BN_free)> y_bignum (BN_bin2bn (reinterpret_cast <const unsigned char *>(y_decode.c_str ()), y_decode.size (), nullptr ), BN_free);
255+
256+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
257+ unsigned char *buf;
258+ OSSL_PARAM *params;
259+ std::unique_ptr<EC_GROUP, decltype (&EC_GROUP_free)> ec_group (EC_GROUP_new_by_curve_name (EC_NAME),EC_GROUP_free);
260+ if (!ec_group.get ()) {
261+ throw UnsupportedKeyException (" Unable to get OpenSSL EC group" );
262+ }
263+
264+ std::unique_ptr<EC_POINT, decltype (&EC_POINT_free)> Q_point (EC_POINT_new (ec_group.get ()), EC_POINT_free);
265+ if (!Q_point.get ()) {
266+ throw UnsupportedKeyException (" Unable to allocate new EC point" );
267+ }
268+
269+ if (!EC_POINT_set_affine_coordinates (ec_group.get (), Q_point.get (), x_bignum.get (), y_bignum.get (), NULL )) {
270+ throw UnsupportedKeyException (" Invalid elliptic curve point in key" );
271+ }
272+
273+ size_t out_len = EC_POINT_point2buf (ec_group.get (), Q_point.get (),POINT_CONVERSION_UNCOMPRESSED,&buf,NULL );
274+ if (out_len == 0 ) {
275+ throw UnsupportedKeyException (" Failed to convert EC point to octet base buffer" );
276+ }
277+
278+ std::unique_ptr<OSSL_PARAM_BLD, decltype (&OSSL_PARAM_BLD_free)> param_build (OSSL_PARAM_BLD_new (), OSSL_PARAM_BLD_free);
279+ if (!param_build.get ()
280+ || !OSSL_PARAM_BLD_push_utf8_string (param_build.get ()," group" ," prime256v1" ,0 )
281+ || !OSSL_PARAM_BLD_push_octet_string (param_build.get ()," pub" ,buf,out_len)
282+ || (params = OSSL_PARAM_BLD_to_param (param_build.get ())) == NULL ) {
283+ throw UnsupportedKeyException (" Failed to build EC public key parameters" );
284+ }
285+
286+ EVP_PKEY *pkey = NULL ;
287+ std::unique_ptr<EVP_PKEY_CTX, decltype (&EVP_PKEY_CTX_free)> ec_ctx (EVP_PKEY_CTX_new_from_name (NULL , " EC" , NULL ), EVP_PKEY_CTX_free);
288+ if (!ec_ctx.get ()) {
289+ throw UnsupportedKeyException (" Failed to set EC PKEY context" );
290+ }
291+
292+ if (EVP_PKEY_fromdata_init (ec_ctx.get ()) <= 0
293+ || EVP_PKEY_fromdata (ec_ctx.get (),&pkey,EVP_PKEY_PUBLIC_KEY,params) <= 0
294+ || pkey == NULL ) {
295+ throw UnsupportedKeyException (" Failed to set the EC public key" );
296+ }
246297
247- std::unique_ptr<EC_KEY, decltype (&EC_KEY_free)> ec (EC_KEY_new_by_curve_name (NID_X9_62_prime256v1), EC_KEY_free);
298+ if (PEM_write_bio_PUBKEY (pubkey_bio.get (), pkey) == 0 ) {
299+ throw UnsupportedKeyException (" Failed to serialize EC public key" );
300+ }
301+ EVP_PKEY_free (pkey);
302+ OSSL_PARAM_free (params);
303+ OPENSSL_free (buf);
304+ #else
305+ std::unique_ptr<EC_KEY, decltype (&EC_KEY_free)> ec (EC_KEY_new_by_curve_name (EC_NAME), EC_KEY_free);
248306 if (!ec.get ()) {
249307 throw UnsupportedKeyException (" OpenSSL does not support the P-256 curve" );
250308 }
@@ -258,8 +316,7 @@ es256_from_coords(const std::string &x_str, const std::string &y_str) {
258316 if (!Q_point.get ()) {
259317 throw UnsupportedKeyException (" Unable to allocate new EC point" );
260318 }
261- std::unique_ptr<BIGNUM, decltype (&BN_free)> x_bignum (BN_bin2bn (reinterpret_cast <const unsigned char *>(x_decode.c_str ()), x_decode.size (), nullptr ), BN_free);
262- std::unique_ptr<BIGNUM, decltype (&BN_free)> y_bignum (BN_bin2bn (reinterpret_cast <const unsigned char *>(y_decode.c_str ()), y_decode.size (), nullptr ), BN_free);
319+
263320 if (EC_POINT_set_affine_coordinates_GFp (params, Q_point.get (), x_bignum.get (), y_bignum.get (), NULL ) != 1 ) {
264321 throw UnsupportedKeyException (" Invalid elliptic curve point in key" );
265322 }
@@ -268,10 +325,10 @@ es256_from_coords(const std::string &x_str, const std::string &y_str) {
268325 throw UnsupportedKeyException (" Unable to set the EC public key" );
269326 }
270327
271- std::unique_ptr<BIO, decltype (&BIO_free_all)> pubkey_bio (BIO_new (BIO_s_mem ()), BIO_free_all);
272- if (PEM_write_bio_EC_PUBKEY (pubkey_bio.get (), ec.get ()) == 0 ) {
328+ if (PEM_write_bio_EC_PUBKEY (pubkey_bio.get (), ec.get ()) == 0 ) {
273329 throw UnsupportedKeyException (" Failed to serialize EC public key" );
274330 }
331+ #endif
275332
276333 char *mem_data;
277334 size_t mem_len = BIO_get_mem_data (pubkey_bio.get (), &mem_data);
@@ -284,29 +341,57 @@ std::string
284341rs256_from_coords (const std::string &e_str, const std::string &n_str) {
285342 auto e_decode = b64url_decode_nopadding (e_str);
286343 auto n_decode = b64url_decode_nopadding (n_str);
344+ std::unique_ptr<BIO, decltype (&BIO_free_all)> pubkey_bio (BIO_new (BIO_s_mem ()), BIO_free_all);
287345 std::unique_ptr<BIGNUM, decltype (&BN_free)> e_bignum (BN_bin2bn (reinterpret_cast <const unsigned char *>(e_decode.c_str ()), e_decode.size (), nullptr ), BN_free);
288346 std::unique_ptr<BIGNUM, decltype (&BN_free)> n_bignum (BN_bin2bn (reinterpret_cast <const unsigned char *>(n_decode.c_str ()), n_decode.size (), nullptr ), BN_free);
347+
348+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
349+ OSSL_PARAM *params;
350+ std::unique_ptr<EVP_PKEY_CTX, decltype (&EVP_PKEY_CTX_free)> rsa_ctx (EVP_PKEY_CTX_new_from_name (NULL , " RSA" , NULL ), EVP_PKEY_CTX_free);
351+ if (!rsa_ctx.get ()) {
352+ throw UnsupportedKeyException (" Failed to set RSA PKEY context" );
353+ }
289354
290- std::unique_ptr<RSA, decltype (&RSA_free)> rsa (RSA_new (), RSA_free);
291- #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
292- rsa->e = e_bignum.get ();
293- rsa->n = n_bignum.get ();
294- rsa->d = nullptr ;
295- #else
296- RSA_set0_key (rsa.get (), n_bignum.get (), e_bignum.get (), nullptr );
297- #endif
298- e_bignum.release ();
299- n_bignum.release ();
355+ std::unique_ptr<OSSL_PARAM_BLD, decltype (&OSSL_PARAM_BLD_free)> param_build (OSSL_PARAM_BLD_new (), OSSL_PARAM_BLD_free);
356+ if (!param_build.get ()
357+ || !OSSL_PARAM_BLD_push_BN_pad (param_build.get ()," e" ,e_bignum.get (),BN_num_bytes (e_bignum.get ()))
358+ || !OSSL_PARAM_BLD_push_BN_pad (param_build.get ()," n" ,n_bignum.get (),BN_num_bytes (n_bignum.get ()))
359+ || (params = OSSL_PARAM_BLD_to_param (param_build.get ())) == NULL ) {
360+ throw UnsupportedKeyException (" Failed to build RSA public key parameters" );
361+ }
362+
363+ EVP_PKEY *pkey = NULL ;
364+ if (EVP_PKEY_fromdata_init (rsa_ctx.get ()) <= 0
365+ || EVP_PKEY_fromdata (rsa_ctx.get (),&pkey,EVP_PKEY_PUBLIC_KEY,params) <= 0
366+ || pkey == NULL ) {
367+ throw UnsupportedKeyException (" Failed to set the RSA public key" );
368+ }
300369
370+ if (PEM_write_bio_PUBKEY (pubkey_bio.get (), pkey) == 0 ) {
371+ throw UnsupportedKeyException (" Failed to serialize RSA public key" );
372+ }
373+ EVP_PKEY_free (pkey);
374+ OSSL_PARAM_free (params);
375+ #else
376+ std::unique_ptr<RSA, decltype (&RSA_free)> rsa (RSA_new (), RSA_free);
377+ #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
378+ rsa->e = e_bignum.get ();
379+ rsa->n = n_bignum.get ();
380+ rsa->d = nullptr ;
381+ #else
382+ RSA_set0_key (rsa.get (), n_bignum.get (), e_bignum.get (), nullptr );
383+ #endif
301384 std::unique_ptr<EVP_PKEY, decltype (&EVP_PKEY_free)> pkey (EVP_PKEY_new (), EVP_PKEY_free);
302385 if (EVP_PKEY_set1_RSA (pkey.get (), rsa.get ()) != 1 ) {
303386 throw UnsupportedKeyException (" Failed to set the public key" );
304387 }
305388
306- std::unique_ptr<BIO, decltype (&BIO_free_all)> pubkey_bio (BIO_new (BIO_s_mem ()), BIO_free_all);
307389 if (PEM_write_bio_PUBKEY (pubkey_bio.get (), pkey.get ()) == 0 ) {
308390 throw UnsupportedKeyException (" Failed to serialize RSA public key" );
309391 }
392+ #endif
393+ e_bignum.release ();
394+ n_bignum.release ();
310395
311396 char *mem_data;
312397 size_t mem_len = BIO_get_mem_data (pubkey_bio.get (), &mem_data);
@@ -359,7 +444,7 @@ normalize_absolute_path(const std::string &path) {
359444
360445void
361446SciToken::deserialize (const std::string &data, const std::vector<std::string> allowed_issuers) {
362- m_decoded.reset (new jwt::decoded_jwt (data));
447+ m_decoded.reset (new jwt::decoded_jwt<jwt::traits::kazuho_picojson> (data));
363448
364449 scitokens::Validator val;
365450 val.add_allowed_issuers (allowed_issuers);
@@ -525,6 +610,43 @@ scitokens::Validator::store_public_ec_key(const std::string &issuer, const std::
525610 if ((size_t )BIO_write (pubkey_bio.get (), public_key.data (), public_key.size ()) != public_key.size ()) {
526611 return false ;
527612 }
613+
614+ std::unique_ptr<BIGNUM, decltype (&BN_free)> x_bignum (BN_new (), BN_free);
615+ std::unique_ptr<BIGNUM, decltype (&BN_free)> y_bignum (BN_new (), BN_free);
616+
617+ #if OPENSSL_VERSION_NUMBER >= 0x30000000L
618+ std::unique_ptr<EVP_PKEY, decltype (&EVP_PKEY_free)> pkey (PEM_read_bio_PUBKEY (pubkey_bio.get (),nullptr ,nullptr ,nullptr ), EVP_PKEY_free);
619+ if (!pkey.get ()) {return false ;}
620+
621+ std::unique_ptr<EC_GROUP, decltype (&EC_GROUP_free)> ec_group (EC_GROUP_new_by_curve_name (EC_NAME),EC_GROUP_free);
622+ if (!ec_group.get ()) {
623+ throw UnsupportedKeyException (" Unable to get OpenSSL EC group" );
624+ }
625+
626+ std::unique_ptr<EC_POINT, decltype (&EC_POINT_free)> q_point (EC_POINT_new (ec_group.get ()), EC_POINT_free);
627+ if (!q_point.get ()) {
628+ throw UnsupportedKeyException (" Unable to get OpenSSL EC point" );
629+ }
630+
631+ OSSL_PARAM *params;
632+ if (!EVP_PKEY_todata (pkey.get (), EVP_PKEY_PUBLIC_KEY, ¶ms)) {
633+ throw UnsupportedKeyException (" Unable to get OpenSSL public key parameters" );
634+ }
635+
636+ void * buf = NULL ;
637+ size_t buf_len, max_len = 256 ;
638+ OSSL_PARAM *p = OSSL_PARAM_locate (params," pub" );
639+ if (!p || !OSSL_PARAM_get_octet_string (p, &buf, max_len, &buf_len)
640+ || !EC_POINT_oct2point (ec_group.get (), q_point.get (), static_cast <unsigned char *>(buf), buf_len, nullptr )) {
641+ throw UnsupportedKeyException (" Failed to to set OpenSSL EC point with public key information" );
642+ }
643+
644+ if (!EC_POINT_get_affine_coordinates (ec_group.get (), q_point.get (), x_bignum.get (), y_bignum.get (), NULL )) {
645+ throw UnsupportedKeyException (" Unable to get OpenSSL affine coordinates" );
646+ }
647+
648+ OSSL_PARAM_free (params);
649+ #else
528650 std::unique_ptr<EC_KEY, decltype (&EC_KEY_free)> pkey
529651 (PEM_read_bio_EC_PUBKEY (pubkey_bio.get (), nullptr , nullptr , nullptr ), EC_KEY_free);
530652 if (!pkey) {return false ;}
@@ -539,11 +661,10 @@ scitokens::Validator::store_public_ec_key(const std::string &issuer, const std::
539661 throw UnsupportedKeyException (" Unable to get OpenSSL EC point" );
540662 }
541663
542- std::unique_ptr<BIGNUM, decltype (&BN_free)> x_bignum (BN_new (), BN_free);
543- std::unique_ptr<BIGNUM, decltype (&BN_free)> y_bignum (BN_new (), BN_free);
544664 if (!EC_POINT_get_affine_coordinates_GFp (params, point, x_bignum.get (), y_bignum.get (), nullptr )) {
545665 throw UnsupportedKeyException (" Unable to get OpenSSL affine coordinates" );
546666 }
667+ #endif
547668
548669 auto x_num = BN_num_bytes (x_bignum.get ());
549670 auto y_num = BN_num_bytes (y_bignum.get ());
@@ -577,7 +698,7 @@ scitokens::Validator::store_public_ec_key(const std::string &issuer, const std::
577698bool
578699scitokens::Enforcer::scope_validator (const jwt::claim &claim, void *myself) {
579700 auto me = reinterpret_cast <scitokens::Enforcer*>(myself);
580- if (claim.get_type () != jwt::claim ::type::string) {
701+ if (claim.get_type () != jwt::json ::type::string) {
581702 return false ;
582703 }
583704 std::string scope = claim.as_string ();
0 commit comments