Chromium Code Reviews| Index: net/socket/ssl_client_socket_openssl.cc |
| =================================================================== |
| --- net/socket/ssl_client_socket_openssl.cc (revision 67990) |
| +++ net/socket/ssl_client_socket_openssl.cc (working copy) |
| @@ -175,6 +175,13 @@ |
| SSL_CTX_set_timeout(ssl_ctx_.get(), kSessionCacheTimeoutSeconds); |
| SSL_CTX_sess_set_cache_size(ssl_ctx_.get(), kSessionCacheMaxEntires); |
| SSL_CTX_set_client_cert_cb(ssl_ctx_.get(), ClientCertCallback); |
| +#if defined(OPENSSL_NPN_NEGOTIATED) |
| + // TODO(kristianm): Only select this if ssl_config_.next_proto is not empty. |
| + // It would be better if the callback were not a global setting, |
| + // but that is an OpenSSL issue. |
| + SSL_CTX_set_next_proto_select_cb(ssl_ctx_.get(), SelectNextProtoCallback, |
| + NULL); |
| +#endif |
| } |
| static int NewSessionCallbackStatic(SSL* ssl, SSL_SESSION* session) { |
| @@ -202,6 +209,14 @@ |
| return socket->ClientCertRequestCallback(ssl, x509, pkey); |
| } |
| + static int SelectNextProtoCallback(SSL* ssl, |
| + unsigned char** out, unsigned char* outlen, |
| + const unsigned char* in, |
| + unsigned int inlen, void* arg) { |
| + SSLClientSocketOpenSSL* socket = Get()->GetClientSocketFromSSL(ssl); |
| + return socket->SelectNextProtoCallback(out, outlen, in, inlen); |
| + } |
| + |
| // This is the index used with SSL_get_ex_data to retrieve the owner |
| // SSLClientSocketOpenSSL object from an SSL instance. |
| int ssl_socket_data_index_; |
| @@ -248,6 +263,7 @@ |
| host_and_port_(host_and_port), |
| ssl_config_(ssl_config), |
| trying_cached_session_(false), |
| + npn_status_(kNextProtoUnsupported), |
| net_log_(transport_socket->socket()->NetLog()) { |
| } |
| @@ -370,8 +386,8 @@ |
| SSLClientSocket::NextProtoStatus SSLClientSocketOpenSSL::GetNextProto( |
| std::string* proto) { |
| - proto->clear(); |
| - return kNextProtoUnsupported; |
| + *proto = npn_proto_; |
| + return npn_status_; |
| } |
| void SSLClientSocketOpenSSL::DoReadCallback(int rv) { |
| @@ -567,6 +583,40 @@ |
| return 0; |
| } |
| +int SSLClientSocketOpenSSL::SelectNextProtoCallback(unsigned char** out, |
| + unsigned char* outlen, |
| + const unsigned char* in, |
| + unsigned int inlen) { |
| +#if defined(OPENSSL_NPN_NEGOTIATED) |
| + if (ssl_config_.next_protos.empty()) { |
| + *outlen = 0; |
|
agl
2010/12/03 15:17:37
*out = "http/1.1";
*outlen = 8;
Kristian_
2010/12/03 15:30:57
I added this in later patch, should I change to th
|
| + return SSL_TLSEXT_ERR_OK; |
| + } |
| + |
| + int status = SSL_select_next_proto( |
| + out, outlen, in, inlen, |
| + reinterpret_cast<const unsigned char*>(ssl_config_.next_protos.data()), |
| + ssl_config_.next_protos.size()); |
| + |
| + npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); |
| + switch (status) { |
| + //case OPENSSL_NPN_UNSUPPORTED: |
|
agl
2010/12/03 15:17:37
Why commented out?
Kristian_
2010/12/03 15:30:57
Thanks, it was to test compile on ubuntu where the
|
| + npn_status_ = SSLClientSocket::kNextProtoUnsupported; |
| + break; |
| + //case OPENSSL_NPN_NEGOTIATED: |
| + npn_status_ = SSLClientSocket::kNextProtoNegotiated; |
| + break; |
| + //case OPENSSL_NPN_NO_OVERLAP: |
| + npn_status_ = SSLClientSocket::kNextProtoNoOverlap; |
| + break; |
| + default: |
| + NOTREACHED() << status; |
| + break; |
| + } |
| +#endif |
| + return SSL_TLSEXT_ERR_OK; |
| +} |
| + |
| int SSLClientSocketOpenSSL::DoVerifyCert(int result) { |
| DCHECK(server_cert_); |
| GotoState(STATE_VERIFY_CERT_COMPLETE); |