Skip to content

Commit 4916492

Browse files
authored
Merge pull request #96 from ColeBollig/Openssl_3_0-update
Openssl 3 0 update
2 parents 66f1a76 + 9ff3770 commit 4916492

File tree

89 files changed

+33764
-1587
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+33764
-1587
lines changed

.github/workflows/ccpp.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ env:
1515
jobs:
1616
build:
1717

18-
runs-on: ubuntu-latest
19-
2018
strategy:
2119
matrix:
2220
external-gtest: [ YES, NO ]
21+
os: [ ubuntu-latest, ubuntu-22.04 ]
2322

24-
name: Build with external_gtest=${{ matrix.external-gtest }}
23+
runs-on: ${{ matrix.os }}
24+
name: Build with external_gtest=${{ matrix.external-gtest }} on ${{ matrix.os }}
2525

2626
steps:
2727
- uses: actions/checkout@v1

CMakeLists.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ project( scitokens-cpp
88

99
option( SCITOKENS_BUILD_UNITTESTS "Build the scitokens-cpp unit tests" OFF )
1010
option( SCITOKENS_EXTERNAL_GTEST "Use an external/pre-installed copy of GTest" OFF )
11-
option( SCITOKENS_WARNINGS_ARE_ERRORS "Turn compiler warnings into build errors" OFF)
1211

1312
set( CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}" )
1413

@@ -39,7 +38,6 @@ endif()
3938

4039
add_library(SciTokens SHARED src/scitokens.cpp src/scitokens_internal.cpp src/scitokens_cache.cpp)
4140
target_compile_features(SciTokens PUBLIC cxx_std_11) # Use at least C++11 for building and when linking to scitokens
42-
target_compile_options(SciTokens PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall $<$<BOOL:${SCITOKENS_WARNINGS_ARE_ERRORS}>:-Werror>>)
4341
target_include_directories(SciTokens PUBLIC ${JWT_CPP_INCLUDES} "${PROJECT_SOURCE_DIR}/src" PRIVATE ${CURL_INCLUDES} ${OPENSSL_INCLUDE_DIRS} ${LIBCRYPTO_INCLUDE_DIRS} ${SQLITE_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS})
4442

4543
target_link_libraries(SciTokens PUBLIC ${OPENSSL_LIBRARIES} ${LIBCRYPTO_LIBRARIES} ${CURL_LIBRARIES} ${SQLITE_LIBRARIES} ${UUID_LIBRARIES})
@@ -57,23 +55,18 @@ add_executable(scitokens-test src/test.cpp)
5755
#target_include_directories(scitokens-test PRIVATE "${PROJECT_SOURCE_DIR}" ${JWT_CPP_INCLUDES} ${CURL_INCLUDES} ${OPENSSL_INCLUDE_DIRS} ${LIBCRYPTO_INCLUDE_DIRS} ${SQLITE_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS})
5856
target_include_directories(scitokens-test PRIVATE "${PROJECT_SOURCE_DIR}" ${JWT_CPP_INCLUDES} ${LIBCRYPTO_INCLUDE_DIRS})
5957
target_link_libraries(scitokens-test SciTokens)
60-
target_compile_options(scitokens-test PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall $<$<BOOL:${SCITOKENS_WARNINGS_ARE_ERRORS}>:-Werror>>)
6158

6259
add_executable(scitokens-verify src/verify.cpp)
6360
target_link_libraries(scitokens-verify SciTokens)
64-
target_compile_options(scitokens-verify PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall $<$<BOOL:${SCITOKENS_WARNINGS_ARE_ERRORS}>:-Werror>>)
6561

6662
add_executable(scitokens-test-access src/test_access.cpp)
6763
target_link_libraries(scitokens-test-access SciTokens)
68-
target_compile_options(scitokens-test-access PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall $<$<BOOL:${SCITOKENS_WARNINGS_ARE_ERRORS}>:-Werror>>)
6964

7065
add_executable(scitokens-list-access src/list_access.cpp)
7166
target_link_libraries(scitokens-list-access SciTokens)
72-
target_compile_options(scitokens-list-access PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall $<$<BOOL:${SCITOKENS_WARNINGS_ARE_ERRORS}>:-Werror>>)
7367

7468
add_executable(scitokens-create src/create.cpp)
7569
target_link_libraries(scitokens-create SciTokens)
76-
target_compile_options(scitokens-create PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall $<$<BOOL:${SCITOKENS_WARNINGS_ARE_ERRORS}>:-Werror>>)
7770

7871
get_directory_property(TARGETS BUILDSYSTEM_TARGETS)
7972
install(

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Building
1515

1616
To build the `scitokens-cpp` library, the following dependencies are needed:
1717

18-
- [jwt-cpp](https://github.com/Thalhammer/jwt-cpp): A header-only C++ library for manipulating
18+
- [jwt-cpp] v0.5.0 or later (https://github.com/Thalhammer/jwt-cpp): A header-only C++ library for manipulating
1919
JWTs.
2020
- OpenSSL 1.0 or later.
2121
- `sqlite3`

src/scitokens_internal.cpp

Lines changed: 141 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
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

1521
using namespace scitokens;
@@ -243,8 +249,60 @@ std::string
243249
es256_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
284341
rs256_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

360445
void
361446
SciToken::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, &params)) {
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::
577698
bool
578699
scitokens::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

Comments
 (0)