<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 8/30/2020 20:19, Jordan Brown wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:0101017441e271f3-92a7df7b-3354-4663-98ef-6ac8b9691939-000000@us-west-2.amazonses.com">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      Well, I can restate the problem that I encountered.<br>
      <br>
      We deliver an integrated storage system.  Under the covers it is a
      modified Solaris running a usual collection of proprietary and
      open-source components.  We supply an administrative user
      interface that, among many other things, lets you manage a list of
      "trusted" certificates - typically CA certificates that a program
      would use to authenticate its peers.  That is, it's the equivalent
      of Firefox's Tools / Options / Privacy & Security /
      Certificates / View Certificates, and the "Servers" and
      "Authorities" tabs there, with the additional tidbit that for each
      certificate you can control which services (e.g. LDAP, et cetera)
      that certificate is trusted for.<br>
      <br>
      When an administrator makes a change to the trusted-certificates
      list, we want that change to take effect, system-wide.<br>
      <br>
      The problem is that that means that some number of processes with
      active OpenSSL contexts need to drop those contexts and recreate
      them, and we don't know which processes those are.  Client
      operations are typically driven through a library, not a separate
      daemon, and so there's no centralized way to know which processes
      might be TLS clients.  In addition, there's the question of how to
      *tell* the process to recreate the context.  Simply restarting
      them may involve disruption of various sorts.<br>
      <br>
      What we'd like would be for OpenSSL to, on every authentication,
      stat the file or directory involved, and if it's changed then wipe
      the in-memory cache.<br>
      <br>
      Yes, aspects of this are system-specific, but that's true of many
      things.  There could easily be an internal API that captures a
      current-stage object, and another that answers "is this still the
      same".  The default implementation could always say "yes".<br>
    </blockquote>
    <p>I'm trying to figure out why you want to replace the context in
      an *existing* connection that is currently passing data rather
      than for new ones.</p>
    <p>For new ones, as I've noted, it already works as you'd likely
      expect it to work, at least in my use case, including in multiple
      threads where the context is picked up and used for connections in
      more than one place.  I've had no trouble with this and a perusal
      of the documentation (but not the code in depth) suggested it
      would be safe due to how OpenSSL does reference counts.</p>
    <p>While some of the client connections to the back end in my use
      case are "controlled" (an app on a phone, for example, so I could
      have control over what happens on the other end and could, for
      example, send down a sequence demanding the client close and
      reconnect) there is also a general web-style interface so the
      connecting party could be on any of the commodity web browsers,
      over which I have no code control.</p>
    <p>Example meta-code:</p>
    <p>get_lock(mutex)</p>
    <p>if (web_context) { /* If there is an existing context then free
      it up */<br>
          SSL_CTX_free(web_context);<br>
          www_context = NULL;    /* It is not ok to attempt to use SSL
      */<br>
      }</p>
    <p></p>
    <p>www_context = SSL_CTX_new(server_method);    /* Now get a new
      context */<br>
      .... (set options, callbacks, verification requirement on certs
      presented, DH and ECDH preferences, cert and key, etc)<br>
      if NOT (happy with the previous sequence of options, setting key
      and cert, etc) {<br>
          SSL_CTX_free(web_context);<br>
          web_context = NULL;<br>
      }</p>
    <p>unlock(mutex)</p>
    <p>Then in the code that actually accepts a new connection:</p>
    <p>get_lock(mutex)<br>
    </p>
    <p>if (web_context) {<br>
          ssl_socket = starttls(inbound_socket, www_context,
      &error);<br>
          .... check non-null to know it's ok, if it is, store and use
      it<br>
      }</p>
    <p>unlock(mutex)</p>
    <p>("starttls" does an SSL_new on the context passed, does the
      SSL_set_fd and SSL_accept, etc, handles any errors generated from
      that and if everything is ok returns the SSL structure)<br>
    </p>
    <p>I've had no trouble with this for a good long time; if there are
      existing connections they continue to run on the previous
      www_context until they close.  New connections come off the new
      one.  You just have to run a mutex to make sure that you don't try
      to create a new connection while the "re-keying" is "in process".</p>
    <div class="moz-signature">-- <br>
      Karl Denninger<br>
      <a href="mailto:karl@denninger.net">karl@denninger.net</a><br>
      <i>The Market Ticker</i><br>
      <font size="-2"><i>[S/MIME encrypted email preferred]</i></font></div>
  </body>
</html>