aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2013-11-22 18:33:50 +0400
committerFedor Indutny <fedor.indutny@gmail.com>2013-12-02 14:48:14 +0400
commit9b8fcff43575592ace3d391ee47184f98ed755df (patch)
tree9c08e5bfcd6d5422ecd46075d7b8687ab42afa0d
parent6877e64fa8ebd1a1017bb4e298a007d98136c133 (diff)
downloadandroid-node-v8-9b8fcff43575592ace3d391ee47184f98ed755df.tar.gz
android-node-v8-9b8fcff43575592ace3d391ee47184f98ed755df.tar.bz2
android-node-v8-9b8fcff43575592ace3d391ee47184f98ed755df.zip
tls: reset NPN callbacks after SNI
SNI callback selects a new SSL_CTX for the connection, which doesn't have NPN callbacks set up.
-rw-r--r--src/node_crypto.cc34
-rw-r--r--src/node_crypto.h2
-rw-r--r--test/simple/test-tls-npn-server-client.js10
3 files changed, 31 insertions, 15 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index e3ece08541..3e77918abb 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -1189,6 +1189,7 @@ int Connection::SelectSNIContextCallback_(SSL *s, int *ad, void* arg) {
p->sniContext_ = Persistent<Value>::New(ret);
SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(
Local<Object>::Cast(ret));
+ p->InitNPN(sc, true);
SSL_set_SSL_CTX(s, sc->ctx_);
} else {
return SSL_TLSEXT_ERR_NOACK;
@@ -1223,20 +1224,7 @@ Handle<Value> Connection::New(const Arguments& args) {
if (is_server) SSL_set_info_callback(p->ssl_, SSLInfoCallback);
-#ifdef OPENSSL_NPN_NEGOTIATED
- if (is_server) {
- // Server should advertise NPN protocols
- SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
- AdvertiseNextProtoCallback_,
- NULL);
- } else {
- // Client should select protocol from advertised
- // If server supports NPN
- SSL_CTX_set_next_proto_select_cb(sc->ctx_,
- SelectNextProtoCallback_,
- NULL);
- }
-#endif
+ p->InitNPN(sc, is_server);
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
if (is_server) {
@@ -1980,6 +1968,24 @@ Handle<Value> Connection::Close(const Arguments& args) {
return True();
}
+
+void Connection::InitNPN(SecureContext* sc, bool is_server) {
+#ifdef OPENSSL_NPN_NEGOTIATED
+ if (is_server) {
+ // Server should advertise NPN protocols
+ SSL_CTX_set_next_protos_advertised_cb(sc->ctx_,
+ AdvertiseNextProtoCallback_,
+ NULL);
+ } else {
+ // Client should select protocol from advertised
+ // If server supports NPN
+ SSL_CTX_set_next_proto_select_cb(sc->ctx_,
+ SelectNextProtoCallback_,
+ NULL);
+ }
+#endif
+}
+
#ifdef OPENSSL_NPN_NEGOTIATED
Handle<Value> Connection::GetNegotiatedProto(const Arguments& args) {
HandleScope scope;
diff --git a/src/node_crypto.h b/src/node_crypto.h
index f1f6334b24..01a052855a 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -190,6 +190,8 @@ class Connection : ObjectWrap {
static v8::Handle<v8::Value> Start(const v8::Arguments& args);
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
+ static void InitNPN(SecureContext* sc, bool is_server);
+
#ifdef OPENSSL_NPN_NEGOTIATED
// NPN
static v8::Handle<v8::Value> GetNegotiatedProto(const v8::Arguments& args);
diff --git a/test/simple/test-tls-npn-server-client.js b/test/simple/test-tls-npn-server-client.js
index d9e8f91806..ef89bd235e 100644
--- a/test/simple/test-tls-npn-server-client.js
+++ b/test/simple/test-tls-npn-server-client.js
@@ -28,7 +28,8 @@ if (!process.features.tls_npn) {
var common = require('../common'),
assert = require('assert'),
fs = require('fs'),
- tls = require('tls');
+ tls = require('tls'),
+ crypto = require('crypto');
function filenamePEM(n) {
return require('path').join(common.fixturesDir, 'keys', n + '.pem');
@@ -42,6 +43,13 @@ var serverOptions = {
key: loadPEM('agent2-key'),
cert: loadPEM('agent2-cert'),
crl: loadPEM('ca2-crl'),
+ SNICallback: function() {
+ return crypto.createCredentials({
+ key: loadPEM('agent2-key'),
+ cert: loadPEM('agent2-cert'),
+ crl: loadPEM('ca2-crl'),
+ }).context;
+ },
NPNProtocols: ['a', 'b', 'c']
};