Commit a2023589 authored by Rainer Jung's avatar Rainer Jung
Browse files

Support for OpenSSL 1.1.0:

- mod_ssl
Look out for "XXX: OpenSSL 1.1.0:" for a few
open problems.

Not tested with test suite yet.

Partial backport of r1728909 from trunk.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x-openssl-1.1.0-compat@1755814 13f79535-47bb-0310-9956-ffa450edef68
parent ca6816a0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -342,7 +342,11 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
    /* We must register the library in full, to ensure our configuration
     * code can successfully test the SSL environment.
     */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    CRYPTO_malloc_init();
#else
    OPENSSL_malloc_init();
#endif
    ERR_load_crypto_strings();
    SSL_load_error_strings();
    SSL_library_init();
+4 −0
Original line number Diff line number Diff line
@@ -858,7 +858,11 @@ static int use_certificate_chain(
    unsigned long err;
    int n;

#if OPENSSL_VERSION_NUMBER < 0x10100000L
    if ((bio = BIO_new(BIO_s_file_internal())) == NULL)
#else
    if ((bio = BIO_new(BIO_s_file())) == NULL)
#endif
        return -1;
    if (BIO_read_filename(bio, file) <= 0) {
        BIO_free(bio);
+38 −2
Original line number Diff line number Diff line
@@ -80,7 +80,11 @@ static apr_status_t upgrade_connection(request_rec *r)
    SSL_set_accept_state(ssl);
    SSL_do_handshake(ssl);

#if OPENSSL_VERSION_NUMBER < 0x10100000L
    if (SSL_get_state(ssl) != SSL_ST_OK) {
#else
    if (SSL_get_state(ssl) != TLS_ST_OK) {
#endif
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02030)
                      "TLS upgrade handshake failed");
        ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
@@ -456,7 +460,11 @@ int ssl_hook_Access(request_rec *r)
         * forbidden in the latter case, let ap_die() handle
         * this recursive (same) error.
         */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        if (SSL_get_state(ssl) != SSL_ST_OK) {
#else
        if (SSL_get_state(ssl) != TLS_ST_OK) {
#endif
            return HTTP_FORBIDDEN;
        }
        ctx = SSL_get_SSL_CTX(ssl);
@@ -622,7 +630,7 @@ int ssl_hook_Access(request_rec *r)
                     !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list));
                     n++)
                {
                    SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n);
                    const SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n);

                    if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) {
                        renegotiate = TRUE;
@@ -633,7 +641,7 @@ int ssl_hook_Access(request_rec *r)
                     !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old));
                     n++)
                {
                    SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n);
                    const SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n);

                    if (sk_SSL_CIPHER_find(cipher_list, value) < 0) {
                        renegotiate = TRUE;
@@ -983,7 +991,11 @@ int ssl_hook_Access(request_rec *r)
            SSL_renegotiate(ssl);
            SSL_do_handshake(ssl);

#if OPENSSL_VERSION_NUMBER < 0x10100000L
            if (SSL_get_state(ssl) != SSL_ST_OK) {
#else
            if (SSL_get_state(ssl) != TLS_ST_OK) {
#endif
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02225)
                              "Re-negotiation request failed");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
@@ -999,16 +1011,24 @@ int ssl_hook_Access(request_rec *r)
             * However, this causes failures in perl-framework currently,
             * perhaps pre-test if we have already negotiated?
             */
            /* XXX: OpenSSL 1.1.0: SSL_set_state() no longer available.
             * Would SSL_renegotiate(ssl) work? */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef OPENSSL_NO_SSL_INTERN
            SSL_set_state(ssl, SSL_ST_ACCEPT);
#else
            ssl->state = SSL_ST_ACCEPT;
#endif
#endif
            SSL_do_handshake(ssl);

            sslconn->reneg_state = RENEG_REJECT;

#if OPENSSL_VERSION_NUMBER < 0x10100000L
            if (SSL_get_state(ssl) != SSL_ST_OK) {
#else
            if (SSL_get_state(ssl) != TLS_ST_OK) {
#endif
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
                              "Re-negotiation handshake failed");
                ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
@@ -1725,11 +1745,19 @@ static void modssl_proxy_info_log(conn_rec *c,
 * so we need to increment here to prevent them from
 * being freed.
 */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define modssl_set_cert_info(info, cert, pkey) \
    *cert = info->x509; \
    CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \
    *pkey = info->x_pkey->dec_pkey; \
    CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_X509_PKEY)
#else
#define modssl_set_cert_info(info, cert, pkey) \
    *cert = info->x509; \
    X509_up_ref(*cert); \
    *pkey = info->x_pkey->dec_pkey; \
    EVP_PKEY_up_ref(*pkey);
#endif

int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
@@ -2068,6 +2096,9 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
     * state machine and move to ABORT if a Client Hello is being
     * read. */
    if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) {
    /* XXX: OpenSSL 1.1.0: Which state machine states to use instead of
     * SSL3_ST_SR_CLNT_HELLO_A and SSL23_ST_SR_CLNT_HELLO_A ? */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        int state = SSL_get_state((SSL *)ssl);

        if (state == SSL3_ST_SR_CLNT_HELLO_A
@@ -2076,6 +2107,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
            ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02042)
                          "rejecting client initiated renegotiation");
        }
#endif
    }
    /* If the first handshake is complete, change state to reject any
     * subsequent client-initiated renegotiation. */
@@ -2279,7 +2311,11 @@ int ssl_callback_SessionTicket(SSL *ssl,
        }

        memcpy(keyname, ticket_key->key_name, 16);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH);
#else
        RAND_bytes(iv, EVP_MAX_IV_LENGTH);
#endif
        EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL,
                           ticket_key->aes_key, iv);
        HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL);
+4 −0
Original line number Diff line number Diff line
@@ -262,6 +262,9 @@ int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
                      "No cert available to check with OCSP");
        return 1;
    }
    /* XXX: OpenSSL 1.1.0: cert->valid not available in OpenSSL 1.1.0
     * and I have found no accessor method. What to do? */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) {
        /* don't do OCSP checking for valid self-issued certs */
        ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
@@ -269,6 +272,7 @@ int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
        X509_STORE_CTX_set_error(ctx, X509_V_OK);
        return 1;
    }
#endif

    /* Create a temporary pool to constrain memory use (the passed-in
     * pool may be e.g. a connection pool). */
+29 −1
Original line number Diff line number Diff line
@@ -529,13 +529,25 @@ static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs,
        resdup = FALSE;
    }
    else if (strcEQ(var, "A_SIG")) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->signature->algorithm));
#else
        ASN1_OBJECT *paobj;
        X509_ALGOR_get0(&paobj, NULL, NULL, X509_get0_tbs_sigalg(xs));
        nid = OBJ_obj2nid(paobj);
#endif
        result = apr_pstrdup(p,
                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        resdup = FALSE;
    }
    else if (strcEQ(var, "A_KEY")) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
        nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->key->algor->algorithm));
#else
        ASN1_OBJECT *paobj;
        X509_PUBKEY_get0_param(&paobj, NULL, 0, NULL, X509_get_X509_PUBKEY(xs));
        nid = OBJ_obj2nid(paobj);
#endif
        result = apr_pstrdup(p,
                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
        resdup = FALSE;
@@ -597,11 +609,15 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *
    for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) {
        if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen)
            && strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
            for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
                                                   xsname->entries);
                 j++) {
                xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
                                                xsname->entries, j);
#else
            for (j = 0; j < X509_NAME_entry_count(xsname); j++) {
                xsne = X509_NAME_get_entry(xsname, j);
#endif

                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));

@@ -903,7 +919,9 @@ static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var)
static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
                       X509_NAME *xn, apr_pool_t *p)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    STACK_OF(X509_NAME_ENTRY) *ents = xn->entries;
#endif
    X509_NAME_ENTRY *xsne;
    apr_hash_t *count;
    int i, nid;
@@ -913,10 +931,16 @@ static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
    count = apr_hash_make(p);

    /* For each RDN... */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    for (i = 0; i < sk_X509_NAME_ENTRY_num(ents); i++) {
         const char *tag;

         xsne = sk_X509_NAME_ENTRY_value(ents, i);
#else
    for (i = 0; i < X509_NAME_entry_count(xn); i++) {
         const char *tag;
         xsne = X509_NAME_get_entry(xn, i);
#endif

         /* Retrieve the nid, and check whether this is one of the nids
          * which are to be extracted. */
@@ -1090,7 +1114,11 @@ apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer,
    for (j = 0; j < count; j++) {
        X509_EXTENSION *ext = X509_get_ext(xs, j);

#if OPENSSL_VERSION_NUMBER < 0x10100000L
        if (OBJ_cmp(ext->object, oid) == 0) {
#else
        if (OBJ_cmp(X509_EXTENSION_get_object(ext), oid) == 0) {
#endif
            BIO *bio = BIO_new(BIO_s_mem());

            /* We want to obtain a string representation of the extensions
Loading