static void ssl_proceed_handshake()

in wb/wb.c [777:867]


static void ssl_proceed_handshake(struct connection *c)
{
    int do_next = 1;

    while (do_next) {
        int ret, ecode;

        ret = SSL_do_handshake(c->ssl);
        ecode = SSL_get_error(c->ssl, ret);

        switch (ecode) {
        case SSL_ERROR_NONE:
            if (verbosity >= 2)
                ssl_print_info(c);
            if (ssl_info == NULL) {
                AB_SSL_CIPHER_CONST SSL_CIPHER *ci;
                X509 *cert;
                int sk_bits, pk_bits, swork;

                ci = SSL_get_current_cipher(c->ssl);
                sk_bits = SSL_CIPHER_get_bits(ci, &swork);
                cert = SSL_get_peer_certificate(c->ssl);
                if (cert)
                    pk_bits = EVP_PKEY_bits(X509_get_pubkey(cert));
                else
                    pk_bits = 0;  /* Anon DH */

                ssl_info = xmalloc(128);
                apr_snprintf(ssl_info, 128, "%s,%s,%d,%d",
                             SSL_get_version(c->ssl),
                             SSL_CIPHER_get_name(ci),
                             pk_bits, sk_bits);
            }
            if (ssl_tmp_key == NULL) {
                EVP_PKEY *key;
                if (SSL_get_server_tmp_key(c->ssl, &key)) {
                    ssl_tmp_key = xmalloc(128);
                    switch (EVP_PKEY_id(key)) {
                    case EVP_PKEY_RSA:
                        apr_snprintf(ssl_tmp_key, 128, "RSA %d bits",
                                     EVP_PKEY_bits(key));
                        break;
                    case EVP_PKEY_DH:
                        apr_snprintf(ssl_tmp_key, 128, "DH %d bits",
                                     EVP_PKEY_bits(key));
                        break;
#ifndef OPENSSL_NO_EC
                    case EVP_PKEY_EC: {
                        const char *cname = NULL;
                        EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key);
                        int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
                        EC_KEY_free(ec);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
                        cname = EC_curve_nid2nist(nid);
#endif
                        if (!cname)
                            cname = OBJ_nid2sn(nid);

                        apr_snprintf(ssl_tmp_key, 128, "ECDH %s %d bits",
                                     cname,
                                     EVP_PKEY_bits(key));
                        break;
                        }
#endif
                    }
                    EVP_PKEY_free(key);
                }
            }
            write_request(c);
            do_next = 0;
            break;
        case SSL_ERROR_WANT_READ:
            set_polled_events(c, APR_POLLIN);
            do_next = 0;
            break;
        case SSL_ERROR_WANT_WRITE:
            set_polled_events(c, APR_POLLOUT);
            do_next = 0;
            break;
        case SSL_ERROR_WANT_CONNECT:
        case SSL_ERROR_SSL:
        case SSL_ERROR_SYSCALL:
            /* Unexpected result */
            BIO_printf(bio_err, "SSL handshake failed (%d).\n", ecode);
            ERR_print_errors(bio_err);
            close_connection(c);
            do_next = 0;
            break;
        }
    }
}