Skip to content

Commit

Permalink
Added convenience function for binary DER to PEM (#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisyakovlev authored Mar 14, 2023
1 parent 73f2341 commit c2b43e6
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 17 deletions.
61 changes: 44 additions & 17 deletions include/jwt-cpp/jwt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename Decode>
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<const unsigned char*>(decodedStr.c_str());

auto c_str = reinterpret_cast<const unsigned char*>(cert_der_str.c_str());

std::unique_ptr<X509, decltype(&X509_free)> cert(
d2i_X509(NULL, &c_str, static_cast<int>(decodedStr.size())), X509_free);
d2i_X509(NULL, &c_str, static_cast<int>(cert_der_str.size())), X509_free);
auto certbio = make_mem_buf_bio();
if (!cert || !certbio) {
ec = error::rsa_error::create_mem_bio_failed;
Expand All @@ -586,6 +576,28 @@ namespace jwt {
return {ptr, static_cast<size_t>(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<typename Decode>
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.
*
Expand All @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions tests/HelperTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ TEST(HelperTest, Base64DER2PemCert) {
ASSERT_EQ(google_cert, cert_pem);
}

TEST(HelperTest, DER2PemCert) {
auto decoded = jwt::base::decode<jwt::alphabet::base64>(
jwt::base::pad<jwt::alphabet::base64>(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<jwt::error::rsa_error>(-1)).message(), "unknown RSA error");
Expand Down

0 comments on commit c2b43e6

Please sign in to comment.