Commit bc06bf54 authored by Doug MacEachern's avatar Doug MacEachern
Browse files

mod_ssl adjustments to help with using toolkits other than OpenSSL:

  Use SSL functions/macros instead of directly dereferencing SSL
  structures wherever possible.
  Add type-casts for the cases where functions return a generic pointer.
  Add $SSL/include to configure search path.
PR:
Obtained from:
Submitted by:	Madhusudan Mathihalli <madhusudan_mathihalli@hp.com>
Reviewed by:	dougm


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/ssl@92800 13f79535-47bb-0310-9956-ffa450edef68
parent 86b5bf08
Loading
Loading
Loading
Loading
+25 −0
Changes for mod_ssl.h: 25 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -345,6 +345,31 @@ typedef enum {

#ifndef X509_V_ERR_CERT_UNTRUSTED
#define X509_V_ERR_CERT_UNTRUSTED 27

#endif

#ifdef OPENSSL_VERSION_NUMBER

#define EVP_PKEY_key_type(k)              (EVP_PKEY_type(k->type))

#define X509_NAME_get_entries(xs)         (xs->entries)
#define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber)

#define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm)
#define X509_get_key_algorithm(xs)       (xs->cert_info->key->algor->algorithm)

#define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data)
#define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length)

#define SSL_CTX_get_extra_certs(ctx)       (ctx->extra_certs)
#define SSL_CTX_set_extra_certs(ctx,value) {ctx->extra_certs = value;}

#define SSL_CIPHER_get_name(s)             (s->name)
#define SSL_CIPHER_get_valid(s)            (s->valid)

#define SSL_SESSION_get_session_id(s)      (s->session_id)
#define SSL_SESSION_get_session_id_length(s) (s->session_id_length)

#endif

#define ssl_verify_error_is_optional(errnum) \
+5 −5
Changes for ssl_engine_init.c: 5 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -604,7 +604,7 @@ void ssl_init_ConfigureServer(server_rec *s, apr_pool_t *p, SSLSrvConfigRec *sc)
                    "CA certificates for client authentication", cpVHostID);
            ssl_die();
        }
        SSL_CTX_set_client_CA_list(sc->pSSLCtx, skCAList);
        SSL_CTX_set_client_CA_list(sc->pSSLCtx, (STACK *)skCAList);
    }

    /*
@@ -628,7 +628,7 @@ void ssl_init_ConfigureServer(server_rec *s, apr_pool_t *p, SSLSrvConfigRec *sc)
     * should take place. This cannot work.
     */
    if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
        skCAList = SSL_CTX_get_client_CA_list(ctx);
        skCAList = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx);
        if (sk_X509_NAME_num(skCAList) == 0)
            ssl_log(s, SSL_LOG_WARN,
                    "Init: Ops, you want to request client authentication, "
@@ -785,7 +785,7 @@ void ssl_init_ConfigureServer(server_rec *s, apr_pool_t *p, SSLSrvConfigRec *sc)
        && sc->pPrivateKey[SSL_AIDX_DSA] != NULL) {
        pKey = X509_get_pubkey(sc->pPublicCert[SSL_AIDX_DSA]);
        if (   pKey != NULL
            && EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA 
            && EVP_PKEY_key_type(pKey) == EVP_PKEY_DSA 
            && EVP_PKEY_missing_parameters(pKey))
            EVP_PKEY_copy_parameters(pKey, sc->pPrivateKey[SSL_AIDX_DSA]);
    }
@@ -924,7 +924,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, apr_pool_t *pp, const ch
     * Process CA certificate bundle file
     */
    if (cpCAfile != NULL) {
        sk = SSL_load_client_CA_file(cpCAfile);
        sk = (STACK_OF(X509_NAME) *)SSL_load_client_CA_file(cpCAfile);
        for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) {
            ssl_log(s, SSL_LOG_TRACE,
                    "CA certificate: %s",
@@ -941,7 +941,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, apr_pool_t *pp, const ch
        apr_dir_open(&dir, cpCApath, p);
        while ((apr_dir_read(&direntry, APR_FINFO_DIRENT, dir)) != APR_SUCCESS) {
            cp = apr_pstrcat(p, cpCApath, "/", direntry.name, NULL);
            sk = SSL_load_client_CA_file(cp);
            sk = (STACK_OF(X509_NAME) *)SSL_load_client_CA_file(cp);
            for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) {
                ssl_log(s, SSL_LOG_TRACE,
                        "CA certificate: %s",
+45 −20
Changes for ssl_engine_kernel.c: 45 added lines, 20 removed lines.
Original line number Diff line number Diff line
@@ -489,7 +489,7 @@ int ssl_hook_Access(request_rec *r)
        if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE)
            pCipher = SSL_get_current_cipher(ssl);
        else {
            skCipherOld = SSL_get_ciphers(ssl);
            skCipherOld = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);
            if (skCipherOld != NULL)
                skCipherOld = sk_SSL_CIPHER_dup(skCipherOld);
        }
@@ -502,7 +502,7 @@ int ssl_hook_Access(request_rec *r)
            return HTTP_FORBIDDEN;
        }
        /* determine whether a renegotiation has to be forced */
        skCipher = SSL_get_ciphers(ssl);
        skCipher = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);
        if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {
            /* optimized way */
            if ((pCipher == NULL && skCipher != NULL) ||
@@ -741,19 +741,23 @@ int ssl_hook_Access(request_rec *r)
         * here because it resets too much of the connection.  So we set the
         * state explicitly and continue the handshake manually.
         */
        ssl_log(r->server, SSL_LOG_INFO, "Requesting connection re-negotiation");
        ssl_log(r->server, SSL_LOG_INFO,
                "Requesting connection re-negotiation");
        if (renegotiate_quick) {
            /* perform just a manual re-verification of the peer */
            ssl_log(r->server, SSL_LOG_TRACE,
                    "Performing quick renegotiation: just re-verifying the peer");
                    "Performing quick renegotiation: "
                    "just re-verifying the peer");
            certstore = SSL_CTX_get_cert_store(ctx);
            if (certstore == NULL) {
                ssl_log(r->server, SSL_LOG_ERROR, "Cannot find certificate storage");
                ssl_log(r->server, SSL_LOG_ERROR,
                        "Cannot find certificate storage");
                return HTTP_FORBIDDEN;
            }
            certstack = SSL_get_peer_cert_chain(ssl);
            certstack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl);
            if (certstack == NULL || sk_X509_num(certstack) == 0) {
                ssl_log(r->server, SSL_LOG_ERROR, "Cannot find peer certificate chain");
                ssl_log(r->server, SSL_LOG_ERROR,
                        "Cannot find peer certificate chain");
                return HTTP_FORBIDDEN;
            }
            cert = sk_X509_value(certstack, 0);
@@ -772,9 +776,11 @@ int ssl_hook_Access(request_rec *r)
        else {
            /* do a full renegotiation */
            ssl_log(r->server, SSL_LOG_TRACE,
                    "Performing full renegotiation: complete handshake protocol");
                    "Performing full renegotiation: "
                    "complete handshake protocol");
            if (r->main != NULL)
                SSL_set_session_id_context(ssl, (unsigned char *)&(r->main), sizeof(r->main));
                SSL_set_session_id_context(ssl, (unsigned char *)&(r->main),
                                           sizeof(r->main));
            else
                SSL_set_session_id_context(ssl, (unsigned char *)&r, sizeof(r));
            /* will need to push to / pull from filters to renegotiate */
@@ -783,11 +789,13 @@ int ssl_hook_Access(request_rec *r)
            SSL_do_handshake(ssl);

            if (SSL_get_state(ssl) != SSL_ST_OK) {
                ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation request failed");
                ssl_log(r->server, SSL_LOG_ERROR,
                        "Re-negotiation request failed");
                ssl_bio_hooks_unset(ssl);
                return HTTP_FORBIDDEN;
            }
            ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake");
            ssl_log(r->server, SSL_LOG_INFO,
                    "Awaiting re-negotiation handshake");
            SSL_set_state(ssl, SSL_ST_ACCEPT);
            SSL_do_handshake(ssl);

@@ -795,7 +803,8 @@ int ssl_hook_Access(request_rec *r)

            if (SSL_get_state(ssl) != SSL_ST_OK) {
                ssl_log(r->server, SSL_LOG_ERROR,
                        "Re-negotiation handshake failed: Not accepted by client!?");
                        "Re-negotiation handshake failed: "
                        "Not accepted by client!?");
                return HTTP_FORBIDDEN;
            }
        }
@@ -1124,7 +1133,7 @@ int ssl_hook_Fixup(request_rec *r)
        apr_table_set(e, "SSL_SERVER_CERT", val);
        val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_CERT");
        apr_table_set(e, "SSL_CLIENT_CERT", val);
        if ((sk = SSL_get_peer_cert_chain(ssl)) != NULL) {
        if ((sk = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl)) != NULL) {
            for (i = 0; i < sk_X509_num(sk); i++) {
                var = apr_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i);
                val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
@@ -1485,11 +1494,14 @@ int ssl_callback_SSLVerify_CRL(
#else
            revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
#endif
            if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(xs)) == 0) {
            if (ASN1_INTEGER_cmp(X509_REVOKED_get_serialNumber(revoked),
                                 X509_get_serialNumber(xs)) == 0) {


                if (sc->nLogLevel >= SSL_LOG_INFO) {
                    char *cp = X509_NAME_oneline(issuer, NULL, 0);
                    long serial = ASN1_INTEGER_get(revoked->serialNumber);
                    long serial = ASN1_INTEGER_get(
                                       X509_REVOKED_get_serialNumber(revoked));

                    ssl_log(s, SSL_LOG_INFO,
                            "Certificate with serial %ld (0x%lX) "
@@ -1520,6 +1532,9 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
    SSLSrvConfigRec *sc;
    long t;
    BOOL rc;
    unsigned char *session_id;
    unsigned int session_id_length;


    /*
     * Get Apache context back through OpenSSL context
@@ -1539,8 +1554,12 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
     * Store the SSL_SESSION in the inter-process cache with the
     * same expire time, so it expires automatically there, too.
     */
    session_id = SSL_SESSION_get_session_id(pNew);
    session_id_length = SSL_SESSION_get_session_id_length(pNew);

    t = (SSL_get_time(pNew) + sc->nSessionCacheTimeout);
    rc = ssl_scache_store(s, pNew->session_id, pNew->session_id_length, t, pNew);
    rc = ssl_scache_store(s, session_id, session_id_length, t, pNew);


    /*
     * Log this cache operation
@@ -1548,7 +1567,7 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
    ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
            "request=SET status=%s id=%s timeout=%ds (session caching)",
            rc == TRUE ? "OK" : "BAD",
            SSL_SESSION_id2sz(pNew->session_id, pNew->session_id_length),
            SSL_SESSION_id2sz(session_id, session_id_length),
            t-time(NULL));

    /*
@@ -1615,6 +1634,9 @@ void ssl_callback_DelSessionCacheEntry(
    SSL_CTX *ctx, SSL_SESSION *pSession)
{
    server_rec *s;
    unsigned char *session_id;
    unsigned int session_id_length;


    /*
     * Get Apache context back through OpenSSL context
@@ -1626,15 +1648,18 @@ void ssl_callback_DelSessionCacheEntry(
    /*
     * Remove the SSL_SESSION from the inter-process cache
     */
    ssl_scache_remove(s, pSession->session_id, pSession->session_id_length);
    session_id = SSL_SESSION_get_session_id(pSession);
    session_id_length = SSL_SESSION_get_session_id_length(pSession);

    ssl_scache_remove(s, session_id, session_id_length);


    /*
     * Log this cache operation
     */
    ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
            "request=REM status=OK id=%s (session dead)",
            SSL_SESSION_id2sz(pSession->session_id,
            pSession->session_id_length));
            SSL_SESSION_id2sz(session_id, session_id_length));

    return;
}
+24 −12
Changes for ssl_engine_vars.c: 24 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -283,8 +283,9 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var)
    }
    else if (ssl != NULL && strcEQ(var, "SESSION_ID")) {
        SSL_SESSION *pSession = SSL_get_session(ssl);
        result = apr_pstrdup(p, SSL_SESSION_id2sz(pSession->session_id, 
                                                 pSession->session_id_length));
        result = apr_pstrdup(p, SSL_SESSION_id2sz(
                                SSL_SESSION_get_session_id(pSession),
                                SSL_SESSION_get_session_id_length(pSession)));
    }
    else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) {
        result = ssl_var_lookup_ssl_cipher(p, c, var+6);
@@ -356,13 +357,15 @@ static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var)
        resdup = FALSE;
    }
    else if (strcEQ(var, "A_SIG")) {
        nid = OBJ_obj2nid(xs->cert_info->signature->algorithm);
        result = apr_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_signature_algorithm(xs));
        result = apr_pstrdup(p, 
                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        resdup = FALSE;
    }
    else if (strcEQ(var, "A_KEY")) {
        nid = OBJ_obj2nid(xs->cert_info->key->algor->algorithm);
        result = apr_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_key_algorithm(xs));
        result = apr_pstrdup(p,
                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        resdup = FALSE;
    }
    else if (strcEQ(var, "CERT")) {
@@ -400,21 +403,30 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *
    char *result;
    X509_NAME_ENTRY *xsne;
    int i, j, n;
    char *data_ptr;
    int data_len;

    result = NULL;

    for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) {
        if (strEQ(var, ssl_var_lookup_ssl_cert_dn_rec[i].name)) {
            for (j = 0; j < sk_X509_NAME_ENTRY_num(xsname->entries); j++) {
                xsne = sk_X509_NAME_ENTRY_value(xsname->entries, j);
                n = OBJ_obj2nid(xsne->object);
            for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
                                                 X509_NAME_get_entries(xsname));
                 j++) {
                xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
                                             X509_NAME_get_entries(xsname), j);

                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
                data_ptr = X509_NAME_ENTRY_get_data_ptr(xsne);
                data_len = X509_NAME_ENTRY_get_data_len(xsne);

                if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid) {
                    result = apr_palloc(p, xsne->value->length+1);
                    apr_cpystrn(result, (char *)xsne->value->data, xsne->value->length+1);
                    result = apr_palloc(p, data_len+1);
                    apr_cpystrn(result, (char *)data_ptr, data_len+1);
#ifdef CHARSET_EBCDIC
                    ascii2ebcdic(result, result, xsne->value->length);
#endif /* CHARSET_EBCDIC */
                    result[xsne->value->length] = NUL;
                    result[data_len] = NUL;
                    break;
                }
            }
+1 −1
Changes for ssl_util.c: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -221,7 +221,7 @@ ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
    if (pCert != NULL)
        pKey = X509_get_pubkey(pCert);
    if (pKey != NULL) {
        switch (EVP_PKEY_type(pKey->type)) {
        switch (EVP_PKEY_key_type(pKey)) {
            case EVP_PKEY_RSA: 
                t = SSL_ALGO_RSA;
                break;
Loading