title: How to get Trusted CA in Apache 2.4.4 mod-ssl // reloading CRL without restart httpd
body: <p>I used to work with a patched Apache 2.2.17 which allowed me to reload the CRL with no need to restart my server.</p>
  
  <p>But it seems since Apache 2.3.15-beta, CRLs are delegated to OpenSSL (sc->server->crl does not exist anymore...)... and I can't see how to adapt my patch to my 2.4.4.</p>
  
  <p>Here are the piece of code I can't use with my new version of apache (and openssl 1.0.1e)</p>
  
  <p><strong>before :</strong></p>
  
  <pre><code>void refresh_revocation_store(server_rec *sr, apr_pool_t *pool)
  {
      SSLSrvConfigRec *sc = mySrvConfig(sr);
      int reload = 0;
  
      /* Some stuff to determine if my crl needs to be reloaded */
      ... 
      reload = 1;
      /*************/
      if (reload) {
          X509_STORE *old, *new;
          new = SSL_X509_STORE_create ((char *)sc-&gt;server-&gt;crl_file,
                                       (char *)sc-&gt;server-&gt;crl_path));
          old = sc-&gt;server-&gt;crl;
          sc-&gt;server-&gt;crl = new;
          X509_STORE_free(old);
      }
  }
  
  STACK_OF(X509) *extract_CAs(STACK_OF(X509_OBJECT) *sk)
  {
    STACK_OF(X509) *skx = sk_X509_new_null();
    X509_OBJECT *tmp;
    int num, i;
  
    if(sk) {
      num = sk_X509_OBJECT_num(sk);
      for(i = 0; i &lt; num; i++) {
        tmp = sk_X509_OBJECT_value(sk, i);
        if(tmp) {
          if(tmp-&gt;type == X509_LU_X509) {
            sk_X509_push(skx, tmp-&gt;data.x509);
          }
        }
      }
    }
    return skx;
  }
  
  STACK_OF(X509_CRL) *extract_CRLs(STACK_OF(X509_OBJECT) *sk)
  {
    STACK_OF(X509_CRL) *skx = sk_X509_CRL_new_null();
    X509_OBJECT *tmp;
    int num, i;
  
    if(sk) {
      num = sk_X509_OBJECT_num(sk);
      for(i = 0; i &lt; num; i++) {
        tmp = sk_X509_OBJECT_value(sk, i);
        if(tmp-&gt;type == X509_LU_CRL) {
          sk_X509_CRL_push(skx, tmp-&gt;data.crl);
        }
      }
    }
    return skx;
  }
  
  
  void ssl_verify(X509_STORE_CTX *ctx, void *dummy)
  {
      STACK_OF(X509) *trusted_CAs = NULL;
      STACK_OF(X509) *untrusted_CAs = ctx-&gt;untrusted;
      STACK_OF(X509_CRL) *crls;
      SSL *ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
      conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
      SSLSrvConfigRec *sc = mySrvConfig(conn-&gt;base_server);
      server_rec *s = conn-&gt;base_server;
      int ok;
      ssl_mutex_on(s);
      trusted_CAs = extract_CAs(sc-&gt;server-&gt;ssl_ctx-&gt;cert_store-&gt;objs);
      if(sc-&gt;server-&gt;crl) {
          refresh_revocation_store(s, conn-&gt;pool);
      crls = extract_CRLs(sc-&gt;server-&gt;crl-&gt;objs);
      } else {
         crls = sk_X509_CRL_new_null();
      }
      /* Starting the chain */
      if (ctx-&gt;chain == NULL) {
          ctx-&gt;chain = sk_X509_new_null();
      }
      ok = is_valid_cert(ctx, trusted_CAs, untrusted_CAs, crls, ctx-&gt;cert, 0);
      sk_X509_free(trusted_CAs);
      ssl_mutex_off(s);
      return (ok == X509_V_OK) ? 1 : 0;
  }
  </code></pre>
  
  <p><strong>And now it would something like this (but does not work, I don't no why)</strong></p>
  
  <pre><code>void refresh_revocation_store(server_rec *sr, apr_pool_t *pool)
  {
          SSLSrvConfigRec *sc = mySrvConfig(sr);
          int reload = 0;
  
          /* Some stuff to determine if my crl needs to be reloaded */
          ... 
          reload = 1;
          /*************/
          if (reload) {
              store = SSL_CTX_get_cert_store(sc-&gt;server-&gt;ssl_ctx);
              if (!store || !X509_STORE_load_locations(store, 
                                                       sc-&gt;server-&gt;crl_file,
                                                       sc-&gt;server-&gt;crl_path)) {
              ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sr);
              ssl_die(sr);
              }
          }
      }
  }
  
  STACK_OF(X509) *extract_CAs(STACK_OF(X509_OBJECT) *sk) {...} // Same as before
  STACK_OF(X509_CRL) *extract_CRLs(STACK_OF(X509_OBJECT) *sk) {...} // Same as before
  
  int ssl_verify(X509_STORE_CTX *ctx, void *dummy)
  {
      STACK_OF(X509) *trusted_CAs = NULL;
      STACK_OF(X509) *untrusted_CAs = ctx-&gt;untrusted;
      STACK_OF(X509_CRL) *crls;
      SSL *ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx);
      conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
      SSLSrvConfigRec *sc = mySrvConfig(conn-&gt;base_server);
      server_rec *s = conn-&gt;base_server;
      int ok;
      ssl_mutex_on(s); 
      X509_STORE *store = SSL_CTX_get_cert_store(sc-&gt;server-&gt;ssl_ctx); 
      if(store) {
          refresh_revocation_store(s, conn-&gt;pool);
          crls = extract_CRLs(store-&gt;objs);
      } else {
          crls = sk_X509_CRL_new_null();
      }
      /* Starting the chain */
      if (ctx-&gt;chain == NULL) {
          ctx-&gt;chain = sk_X509_new_null();
      }
      trusted_CAs = extract_CAs(sc-&gt;server-&gt;ssl_ctx-&gt;cert_store-&gt;objs);
      ok = is_valid_cert(ctx, trusted_CAs, untrusted_CAs, crls, ctx-&gt;cert, 0);
      sk_X509_free(trusted_CAs);
      ssl_mutex_off(s);
      return (ok == X509_V_OK) ? 1 : 0;
  }
  </code></pre>
  
  <p>If anyone has any idea... Please help! I'm going mad with that...</p>
  
  <p>Cheers, 
  Cheloute</p>