Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented BearSSL: CURLOPT_SSL_CTX_FUNCTION #8478

Closed
wants to merge 2 commits into from

Conversation

jan2000
Copy link
Contributor

@jan2000 jan2000 commented Feb 19, 2022

Separated from: #8106

Implemented the CURLOPT_SSL_CTX_FUNCTION option for BearSSL.

Added in 7.11.0 for OpenSSL, in 7.42.0 for wolfSSL and in 7.54.0 for
mbedTLS. Other SSL backends are not supported.
Added in 7.11.0 for OpenSSL, in 7.42.0 for wolfSSL, in 7.54.0 for mbedTLS,
in 7.82.0 in BearSSL. Other SSL backends are not supported.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also change this section in CURLOPT_SSL_CTX_FUNCTION.3. and feature window is currently closed, next one is likely 7.83

return ret;
}
}

if(!br_ssl_client_reset(&backend->ctx, hostname, 0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the ctx callback call come after the reset ctx call?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

br_ssl_client_reset is documented as "Prepare or reset a client context for a new connection", it doesn't completely wipe the context (that's br_ssl_client_zero) or reinitialize the settings that may have been set by the callback. So this is the right place for it.

@jay jay added TLS feature-window A merge of this requires an open feature window labels Feb 19, 2022
@jan2000
Copy link
Contributor Author

jan2000 commented Feb 20, 2022

To further clarify, my own use case for the context function is to inject entropy into the engine on an OS (ECOS) that does not support the native entropy sources supported by BearSSL. See the example below.

This must be done before br_ssl_client_reset:

A possible failure condition is when no initial entropy was injected, and none could be obtained from the OS (either OS randomness gathering is not supported, or it failed).
https://www.bearssl.org/apidoc/bearssl__ssl_8h.html#a847209e73dae3ec3a730041337c785b5

/* BearSSL specific */
#include <bearssl.h>
#include <curl/curl.h>
#include <stdio.h>
#include <time.h>

/*
 * CURLOPT_SSL_CTX_FUNCTION EXAMPLE: inject entropy into the BearSSL engine
 *
 * Inject entropy on OS/architecture that does not support an entropy
 * source that is implemented in BearSSL (RDRAND, getentropy,
 * /dev/urandom, CryptGenRandom).
 *
 * Excerpt from br_ssl_engine_inject_entropy documentation:
 *
 * In all generality, "entropy" must here be considered to mean "that which
 * the attacker cannot predict". If your OS/architecture does not have a
 * suitable source of randomness, then you can make do with the combination
 * of a large enough secret value (possibly a copy of an asymmetric private
 * key that you also store on the system) AND a non-repeating value (e.g.
 * current time, provided that the local clock cannot be reset or altered
 * by the attacker).
 */

static CURLcode my_sslctx_fn(CURL *curl, void *ssl_ctx,
                                         void *usr_ptr)
{
  br_ssl_client_context *cc = (br_ssl_client_context *) ssl_ctx;
  char *secret = (char *) usr_ptr;
  char buf[32];
  struct timespec ts;
  (void) curl;
  int i;

  if(clock_gettime(CLOCK_REALTIME, &ts))
    return CURLE_FAILED_INIT;

  /* Combine the clock and our secret to have a non-repeating value */
  for(i = 0; i < 32; i++)
    buf[i] = (char) (secret[i] ^ ((char *) &ts)[i % sizeof(ts)]);

  br_ssl_engine_inject_entropy(&cc->eng, buf, 32);
  return CURLE_OK;
}

int main(void)
{
  CURL *curl;
  CURLcode ret;
  /* If we do not have a suitable source of randomness, then we have
   * to resort to a secret string of bytes. */
  char secret[32] = "EXAMPLE \0NLY! USE A R\xEAL SECRET!!";

  curl_global_init(CURL_GLOBAL_ALL);
  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L);
  curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");

  curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, my_sslctx_fn);
  curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, (void *) &secret);

  ret = curl_easy_perform(curl);
  if(!ret)
    printf("*** transfer succeeded ***\n");
  else
    printf("*** transfer failed %s***\n", curl_easy_strerror(ret));

  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

@bagder
Copy link
Member

bagder commented Mar 10, 2022

This PR has conflicts now. Can you please fix those and force-push?

@jan2000 jan2000 force-pushed the bearssl-add-ssl-ctx-function branch from 256d1af to 53dba7d Compare March 10, 2022 23:11
@bagder bagder closed this in 3b4a353 Mar 12, 2022
@bagder
Copy link
Member

bagder commented Mar 12, 2022

Thanks!

@jan2000 jan2000 deleted the bearssl-add-ssl-ctx-function branch April 22, 2024 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-window A merge of this requires an open feature window TLS
Development

Successfully merging this pull request may close these issues.

None yet

4 participants