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;
}
}
}