int krypt_do_handshake(krypt_t *kconn, uint8_t *buf, size_t buf_data_size) { int ret = 0; int nbyte = 0; int status = -1; if (buf != NULL && buf_data_size > 0) { nbyte = BIO_write(kconn->network_bio, buf, buf_data_size); } ret = SSL_do_handshake(kconn->ssl); jlog(L_NOTICE, "SSL state: %s", SSL_state_string_long(kconn->ssl)); if (ret > 0 && !SSL_is_init_finished(kconn->ssl)) { // Need more data to continue ? jlog(L_ERROR, "handshake need more data to continue ??"); status = 1; } else if (ret > 0 && SSL_is_init_finished(kconn->ssl)) { // Handshake successfully completed post_handshake_check(kconn); kconn->status = KRYPT_SECURE; status = 0; } else if (ret == 0) { // Error kconn->status = KRYPT_FAIL; jlog(L_ERROR, "ssl_get_error: %d\n", SSL_get_error(kconn->ssl, ret)); ssl_error_stack(); jlog(L_ERROR, "handshake error"); status = -1; } else if (ret < 0) { // Need more data to continue status = 1; } nbyte = BIO_ctrl_pending(kconn->network_bio); if (nbyte > 0) { // Read pending data into the BIO nbyte = BIO_read(kconn->network_bio, kconn->buf_encrypt, kconn->buf_encrypt_size); kconn->buf_encrypt_data_size = nbyte; // FIXME dynamic buffer } return status; }
// ************************************************************ // Do SSL handshake if necessary // return code: // 1 SSL handshake is finished already, success // 0 SSL handshake in progress // -1 failure // ************************************************************ int ACE_SSL_Asynch_Stream::do_SSL_handshake (void) { if (SSL_is_init_finished (this->ssl_)) { if (!handshake_complete_) { handshake_complete_ = true; if (!post_handshake_check ()) { return -1; } } return 1; } if (this->flags_ & SF_REQ_SHUTDOWN) return -1; int retval = -1; switch (this->type_) { case ST_CLIENT: retval = ::SSL_connect (this->ssl_); break; case ST_SERVER: retval = ::SSL_accept (this->ssl_); break; default: ACELIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) ACE_SSL_Asynch_Stream %p\n"), ACE_TEXT ("- invalid stream type")), -1); } int status = ::SSL_get_error (this->ssl_, retval); switch (status) { case SSL_ERROR_NONE: break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_CONNECT: //case SSL_ERROR_WANT_ACCEPT: case SSL_ERROR_WANT_X509_LOOKUP: return 0; case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_SYSCALL: default: this->print_error (status, ACE_TEXT ("Handshake error")); return -1; } return 1; }