From c2b43e67c171cae332f7bc87b8e2a3fed7dc8e5a Mon Sep 17 00:00:00 2001 From: Dennis Yakovlev <37023180+dennisyakovlev@users.noreply.github.com> Date: Tue, 14 Mar 2023 12:00:41 -0400 Subject: [PATCH] Added convenience function for binary DER to PEM (#283) --- include/jwt-cpp/jwt.h | 61 +++++++++++++++++++++++++++++++------------ tests/HelperTest.cpp | 8 ++++++ 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/include/jwt-cpp/jwt.h b/include/jwt-cpp/jwt.h index ec63b64c7..b257cdd03 100644 --- a/include/jwt-cpp/jwt.h +++ b/include/jwt-cpp/jwt.h @@ -543,28 +543,18 @@ namespace jwt { } /** - * \brief Convert the certificate provided as base64 DER to PEM. - * - * This is useful when using with JWKs as x5c claim is encoded as base64 DER. More info - * (here)[https://tools.ietf.org/html/rfc7517#section-4.7] + * \brief Convert the certificate provided as DER to PEM. * - * \tparam Decode is callabled, taking a string_type and returns a string_type. - * It should ensure the padding of the input and then base64 decode and return - * the results. - * - * \param cert_base64_der_str String containing the certificate encoded as base64 DER - * \param decode The function to decode the cert - * \param ec error_code for error_detection (gets cleared if no error occures) + * \param cert_der_str String containing the certificate encoded as base64 DER + * \param ec error_code for error_detection (gets cleared if no error occures) */ - template - std::string convert_base64_der_to_pem(const std::string& cert_base64_der_str, Decode decode, - std::error_code& ec) { + inline std::string convert_der_to_pem(const std::string& cert_der_str, std::error_code& ec) { ec.clear(); - const auto decodedStr = decode(cert_base64_der_str); - auto c_str = reinterpret_cast(decodedStr.c_str()); + + auto c_str = reinterpret_cast(cert_der_str.c_str()); std::unique_ptr cert( - d2i_X509(NULL, &c_str, static_cast(decodedStr.size())), X509_free); + d2i_X509(NULL, &c_str, static_cast(cert_der_str.size())), X509_free); auto certbio = make_mem_buf_bio(); if (!cert || !certbio) { ec = error::rsa_error::create_mem_bio_failed; @@ -586,6 +576,28 @@ namespace jwt { return {ptr, static_cast(len)}; } + /** + * \brief Convert the certificate provided as base64 DER to PEM. + * + * This is useful when using with JWKs as x5c claim is encoded as base64 DER. More info + * (here)[https://tools.ietf.org/html/rfc7517#section-4.7] + * + * \tparam Decode is callabled, taking a string_type and returns a string_type. + * It should ensure the padding of the input and then base64 decode and return + * the results. + * + * \param cert_base64_der_str String containing the certificate encoded as base64 DER + * \param decode The function to decode the cert + * \param ec error_code for error_detection (gets cleared if no error occures) + */ + template + std::string convert_base64_der_to_pem(const std::string& cert_base64_der_str, Decode decode, + std::error_code& ec) { + ec.clear(); + const auto decoded_str = decode(cert_base64_der_str); + return convert_der_to_pem(decoded_str, ec); + } + /** * \brief Convert the certificate provided as base64 DER to PEM. * @@ -607,6 +619,21 @@ namespace jwt { error::throw_if_error(ec); return res; } + + /** + * \brief Convert the certificate provided as DER to PEM. + * + * \param cert_der_str String containing the DER certificate + * \param decode The function to decode the cert + * \throw rsa_exception if an error occurred + */ + inline std::string convert_der_to_pem(const std::string& cert_der_str) { + std::error_code ec; + auto res = convert_der_to_pem(cert_der_str, ec); + error::throw_if_error(ec); + return res; + } + #ifndef JWT_DISABLE_BASE64 /** * \brief Convert the certificate provided as base64 DER to PEM. diff --git a/tests/HelperTest.cpp b/tests/HelperTest.cpp index c4ad6c4d5..9164875d5 100644 --- a/tests/HelperTest.cpp +++ b/tests/HelperTest.cpp @@ -17,6 +17,14 @@ TEST(HelperTest, Base64DER2PemCert) { ASSERT_EQ(google_cert, cert_pem); } +TEST(HelperTest, DER2PemCert) { + auto decoded = jwt::base::decode( + jwt::base::pad(google_cert_base64_der) + ); + auto cert_pem = jwt::helper::convert_der_to_pem(decoded); + ASSERT_EQ(google_cert, cert_pem); +} + TEST(HelperTest, ErrorCodeMessages) { ASSERT_EQ(std::error_code(jwt::error::rsa_error::ok).message(), "no error"); ASSERT_EQ(std::error_code(static_cast(-1)).message(), "unknown RSA error");