Repository: puma/puma
File: ext/puma_http11/mini_ssl.c (C)

Code before:
  else {
    SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
  }

  dh = get_dh2048();
  SSL_CTX_set_tmp_dh(ctx, dh);

#if OPENSSL_VERSION_NUMBER < 0x10002000L
  // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
  // longer needed.
  ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  if (ecdh) {
    SSL_CTX_set_tmp_ecdh(ctx, ecdh);
    EC_KEY_free(ecdh);
  }
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
  SSL_CTX_set_ecdh_auto(ctx, 1);
#endif

  if (NIL_P(verify_mode)) {
    /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
  } else {
    SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
  }
  // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
  rb_obj_freeze(self);
  return self;
}

VALUE engine_init_server(VALUE self, VALUE sslctx) {
  ms_conn* conn;
  VALUE obj;
  SSL_CTX* ctx;
  SSL* ssl;

  conn = engine_alloc(self, &obj);

  TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);

  ssl = SSL_new(ctx);
  conn->ssl = ssl;
  SSL_set_app_data(ssl, NULL);
  SSL_set_bio(ssl, conn->read, conn->write);
  SSL_set_accept_state(ssl);
  return obj;
}

VALUE engine_init_client(VALUE klass) {
  VALUE obj;
  ms_conn* conn = engine_alloc(klass, &obj);
#ifdef HAVE_DTLS_METHOD

Review comment (refactor):
Using `Random::DEFAULT` is somewhat deprecated (it's global state between threads, it can cause extra contention).
There is `Random.bytes` (since 2.6) which does not have that being-global issue.
Both of these are anyway not cryptographically secure.
I'm not sure whether it should be cryptographically secure here, but given the context it sounds like it might.

There is `Random.urandom(number_of_bytes)`, that's cryptographically secure and should not have the problems of RAND_bytes(). It seems available only since Ruby 2.5 though.

Probably no easy answer here.
An alternative might be to do the same thing as
https://github.com/ruby/openssl/blob/01b7cace08ef83b91a524c751b239d0bfb3292af/lib/openssl/ssl.rb#L495-L496
and define that in some Ruby helper method called from here.

Code after:
  else {
    SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
  }

  dh = get_dh2048();
  SSL_CTX_set_tmp_dh(ctx, dh);

#if OPENSSL_VERSION_NUMBER < 0x10002000L
  // Remove this case if OpenSSL 1.0.1 (now EOL) support is no
  // longer needed.
  ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
  if (ecdh) {
    SSL_CTX_set_tmp_ecdh(ctx, ecdh);
    EC_KEY_free(ecdh);
  }
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
  SSL_CTX_set_ecdh_auto(ctx, 1);
#endif

  if (NIL_P(verify_mode)) {
    /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
  } else {
    SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
  }

  session_id_bytes = rb_funcall(rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
                                rb_intern_const("bytes"),
                                1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
  SSL_CTX_set_session_id_context(ctx,
                                 (unsigned char *) RSTRING_PTR(session_id_bytes),
                                 SSL_MAX_SSL_SESSION_ID_LENGTH);

  // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
  rb_obj_freeze(self);
  return self;
}

VALUE engine_init_server(VALUE self, VALUE sslctx) {
  ms_conn* conn;
  VALUE obj;
  SSL_CTX* ctx;
  SSL* ssl;

  conn = engine_alloc(self, &obj);

  TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);

  ssl = SSL_new(ctx);
  conn->ssl = ssl;
  SSL_set_app_data(ssl, NULL);
  SSL_set_bio(ssl, conn->read, conn->write);