Skip to content

[#600] Add TLS SNI hostname to client options #602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 18, 2016
Merged

[#600] Add TLS SNI hostname to client options #602

merged 1 commit into from
Feb 18, 2016

Conversation

theopolis
Copy link

The same notes from #601, make note of the significant changes induced by the local .clang-format.

@theopolis
Copy link
Author

@glynos, feel free to close #601 if you are no longer accepting merges to the 0.12-devel branch. This should build against master.


tcp_socket_.reset(new asio::ip::tcp::socket(
service_, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), source_port)));
socket_.reset(new asio::ssl::stream<asio::ip::tcp::socket &>(
*(tcp_socket_.get()), *context_));

if (sni_hostname_)
SSL_set_tlsext_host_name(socket_->native_handle(),
const_cast<char *>(sni_hostname_->c_str()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little surprised that this is called directly -- are you aware of whether there's something in Boost.Asio that allows you to do this as some sort of pass-through? Maybe through the context_?

Also, I don't think the const-cast is safe -- why does it actually need to be casted away? Will it be used as a buffer? If so I think this could totally screw up the string in sni_hostname_ in non-trivial ways. I do not have a good suggestion how else to do this, but this seems rife with peril.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, unfortunately there's no abstraction within ASIO. And you cannot apply SSL_CTRL_SET_TLSEXT_HOSTNAME to the context, only the SSL object. I've tried just this! In #601 I used the expanded macro function from OpenSSL, modifying it to use SSL_CTX_ctrl and SNI fails. The server_name TLS extension is never applied/used.

See the following for the expansion of SSL_set_tlsext_host_name:

./tls1.h:298:#define SSL_set_tlsext_host_name(s,name) \
./tls1.h-299-SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)

As far as the const_casting away the const, I definitely 100% agree it's scary-- but since we're working with the OpenSSL APIs I am bound to assumptions on the cmd provided to the underlying call (defined in ssl.h) to:

long SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);

And the use of it's parg in this case (from s3_lib.c):

case SSL_CTRL_SET_TLSEXT_HOSTNAME:
    if (larg == TLSEXT_NAMETYPE_host_name) {
        size_t len;

        OPENSSL_free(s->tlsext_hostname);
        s->tlsext_hostname = NULL;

        ret = 1;
        if (parg == NULL)
            break;
        len = strlen((char *)parg);
        if (len == 0 || len > TLSEXT_MAXLEN_host_name) {
            SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
            return 0;
        }
        if ((s->tlsext_hostname = OPENSSL_strdup((char *)parg)) == NULL) {
            SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
            return 0;
        }
    } else {
        SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
        return 0;
    }
    break;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation @theopolis -- I appreciate the detail.

One more question on the const_cast<...> -- have you tried without it? Does it error out? Because if I look closely i see that macro expanding and performing the cast itself (strlen((char*)parg)) so we strictly don't need that in the calling code. I suppose spelling out const_cast<...> explicitly gets my spider senses tingling, especially anything involving SSL and all the potential issues lurking around it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I'd guess the explicit cast from the void* would not complain. I'll see what Travis/clang thinks in a few hours. :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis seems to be happy here, so I'm happy to merge. :)

Thanks @theopolis!

deanberris added a commit that referenced this pull request Feb 18, 2016
[#600] Add TLS SNI hostname to client options
@deanberris deanberris merged commit 413f099 into cpp-netlib:master Feb 18, 2016
@deanberris
Copy link
Member

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants