ssl_ctx.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "cpr/ssl_ctx.h"
  2. #if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
  3. #ifdef OPENSSL_BACKEND_USED
  4. #include <openssl/err.h>
  5. #include <openssl/safestack.h>
  6. #include <openssl/ssl.h>
  7. namespace cpr {
  8. /**
  9. * The ssl_ctx parameter is actually a pointer to the SSL library's SSL_CTX for OpenSSL.
  10. * If an error is returned from the callback no attempt to establish a connection is made and
  11. * the perform operation will return the callback's error code.
  12. *
  13. * Sources: https://curl.se/libcurl/c/CURLOPT_SSL_CTX_FUNCTION.html
  14. * https://curl.se/libcurl/c/CURLOPT_SSL_CTX_DATA.html
  15. */
  16. CURLcode sslctx_function_load_ca_cert_from_buffer(CURL* /*curl*/, void* sslctx, void* raw_cert_buf) {
  17. // Check arguments
  18. if (raw_cert_buf == nullptr || sslctx == nullptr) {
  19. printf("Invalid callback arguments\n");
  20. return CURLE_ABORTED_BY_CALLBACK;
  21. }
  22. // Setup pointer
  23. X509_STORE* store = nullptr;
  24. X509* cert = nullptr;
  25. BIO* bio = nullptr;
  26. char* cert_buf = static_cast<char*>(raw_cert_buf);
  27. // Create a memory BIO using the data of cert_buf.
  28. // Note: It is assumed, that cert_buf is nul terminated and its length is determined by strlen.
  29. bio = BIO_new_mem_buf(cert_buf, -1);
  30. // Load the PEM formatted certicifate into an X509 structure which OpenSSL can use.
  31. PEM_read_bio_X509(bio, &cert, nullptr, nullptr);
  32. if (cert == nullptr) {
  33. printf("PEM_read_bio_X509 failed\n");
  34. return CURLE_ABORTED_BY_CALLBACK;
  35. }
  36. // Get a pointer to the current certificate verification storage
  37. store = SSL_CTX_get_cert_store(static_cast<SSL_CTX*>(sslctx));
  38. // Add the loaded certificate to the verification storage
  39. int status = X509_STORE_add_cert(store, cert);
  40. if (status == 0) {
  41. printf("Error adding certificate\n");
  42. return CURLE_ABORTED_BY_CALLBACK;
  43. }
  44. // Decrement the reference count of the X509 structure cert and frees it up
  45. X509_free(cert);
  46. // Free the entire bio chain
  47. BIO_free(bio);
  48. // The CA certificate was loaded successfully into the verification storage
  49. return CURLE_OK;
  50. }
  51. } // namespace cpr
  52. #endif // OPENSSL_BACKEND_USED
  53. #endif // SUPPORT_CURLOPT_SSL_CTX_FUNCTION