i'm working on implementing the proxy extensions for mod_ssl in 2.0.
the 1.3 based implementation duplicates a bunch of code, for example
the directives:

SSLProxyProtocol - same as SSLProtocol

SSLProxyCipherSuite - same as SSLCipherSuite

SSLProxyVerify - same as SSLVerifyClient

SSLProxyVerifyDepth - same as SSLVerifyDepth

SSLProxyCACertificateFile - same as SSLCACertificateFile

SSLProxyCACertificatePath - same as SSLCACertificatePath

SSLProxyMachineCertificateFile
SSLProxyMachineCertificatePath - similar to SSLCertificateFile and
                                            SSLCertificateKeyFile

ssl_ext_mp_init() duplicates much of ssl_init_Module:
- configuring verify
- configuring ssl protocol
- creating an SSL_CTX (though somewhat different, proxy needs to use
                       *_client_method(), server needs to use *_server_method())
- configuring CA Certificates
- configuring cipher suite
- setting session cache callbacks
- etc.

ssl_engine_ext.c:ssl_ext_mp_verify_cb and
ssl_engine_kernel.c:ssl_callback_SSLVerify are nearly identical
functionality wise.

the way i see it, most of this duplication can be folded, with a few
conditionals depending on being a client (the proxy) or server.
and this is pretty much a requirement if the ssl proxy is to use the
existing ssl filters.

required changes would start with splitting up SSLSrvConfigRec.  i've
included a prototype below.  moves most of the structure into a
"context" structure and what remains of the old SSLSrvConfigRec is log
file, log level, etc.  the new "context" structure can be used for
both the server and client (proxy).  the server config structure now
has two of these "context" structures, one for the server and one for
the proxy client.
i've taken the liberty of dropping hungarian notation in the process.

from there, existing functions would need to be adjusted to the new
structure(s).  then existing functions made generic to work with both a
server and client (proxy) context, which would be a few conditionals.

the main differences would then be the certs/keys, for which the
server has 1-2 configured at startup (SSL_CTX_use_{PrivateKey,certificate)
and the proxy has any number selected at request time with a client
specific callback (SSL_CTX_set_client_cert_cb).  another tricky part
would supporting encrypted keys for proxy client certs, which the 1.3
based module currently does not.  but that would be a different
project for a rainy day.  in the end if all goes as planned, once the
mod_ssl core has been re-arranged to be more generic, ssl_engine_ext.c
would shrink next to nothing and mod_proxy would call 1 optional
function to support ssl.  the SSLProxy* directives would still exist,
but would be using the same functions as the SSL* directives in most
cases.  thoughts?

typedef enum {
    /* we can be a client or a server */
    SSL_METHOD_TYPE_CLIENT,
    SSL_METHOD_TYPE_SERVER
} ssl_method_type_e;

typedef struct {
    /* 
     * server only has 1-2 certs/keys
     * 1 RSA and/or 1 DSA
     */
    const char  *public_cert_file[SSL_AIDX_MAX];
    const char  *private_key_file[SSL_AIDX_MAX];
    X509        *public_cert[SSL_AIDX_MAX];
    EVP_PKEY    *private_key[SSL_AIDX_MAX];
} ssl_server_pkey_info_t;

typedef struct {
    /*
     * client (e.g. proxy) can have any number of 
     * cert/key pairs
     */
    const char  *client_certificate_file;
    const char  *client_certificate_path;
    STACK_OF(X509_INFO) *certs;
} ssl_client_pkey_info_t;

typedef struct {
    SSL_CTX *ssl_ctx;
    ssl_method_type_e method; /* client or server */

    union {
        /* we are one or the other */
        ssl_server_pkey_info_t server;
        ssl_client_pkey_info_t client;
    } pkey_info;

    /* config for handling encrypted keys */
    ssl_pphrase_t pass_phrase_dialog_type;
    const char  *pass_phrase_dialog_path;

    /* known/trusted CAs */
    const char  *ca_certificate_path;
    const char  *ca_certificate_file;
    const char  *certificate_chain;

    /* certificate revocation list */
    const char  *crl_path;
    const char  *crl_file;
    X509_STORE  *crl_store;

    const char  *cipher_suite;
    ssl_proto_t  protocol;

    /* for client or downstream server */
    int          verify_depth;
    ssl_verify_t verify_client;

    int          session_cache_timeout;
} ssl_srv_ctx_t;

typedef struct {
    SSLModConfigRec *mc;
    const char    *vhost_id;
    BOOL           enabled;
    apr_file_t    *log_file;
    int            log_level;
    ssl_srv_ctx_t *server;
    ssl_srv_ctx_t *proxy;
} ssl_srv_config_t; /* was SSLSrvConfigRec */

Reply via email to