diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-10-22 16:54:05 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-10-22 16:54:05 +0000 |
commit | b5f2b5e1a20610e63c5b66f98e7ed01ff10c189a (patch) | |
tree | 8a675a6723a9a22fcdaa4c3d4ef0e7de1711943d /ext/openssl | |
parent | d7d779b59485113d65fff6cc8aaf0b4a20fb9025 (diff) | |
download | ruby-b5f2b5e1a20610e63c5b66f98e7ed01ff10c189a.tar.gz |
ALPN also uses the same logic [Bug #11369]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52228 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/ossl_ssl.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index ae9f3ca8d7..f1d5e61b1e 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -581,56 +581,58 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, } static int -ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) +ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen) { - int i = 0; - VALUE sslctx_obj, cb, protocols, selected; - - sslctx_obj = (VALUE) arg; - cb = rb_iv_get(sslctx_obj, "@npn_select_cb"); - protocols = rb_ary_new(); + VALUE selected; + long len; + unsigned char l; + VALUE protocols = rb_ary_new(); /* The format is len_1|proto_1|...|len_n|proto_n\0 */ - while (in[i]) { - VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]); + while (l = *in++) { + VALUE protocol; + if (l > inlen) { + ossl_raise(eSSLError, "Invalid protocol name list"); + } + protocol = rb_str_new((const char *)in, l); rb_ary_push(protocols, protocol); - i += in[i] + 1; + in += l; + inlen -= l; } selected = rb_funcall(cb, rb_intern("call"), 1, protocols); StringValue(selected); - i = RSTRING_LENINT(selected); - if (i < 1 || i >= 256) { - ossl_raise(eSSLError, "Selected protocol must have length 1..255"); + len = RSTRING_LEN(selected); + if (len < 1 || len >= 256) { + ossl_raise(eSSLError, "Selected protocol name must have length 1..255"); } - *out = (unsigned char *) StringValuePtr(selected); - *outlen = i; + *out = (unsigned char *)RSTRING_PTR(selected); + *outlen = (unsigned char)len; + return SSL_TLSEXT_ERR_OK; } +static int +ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) +{ + VALUE sslctx_obj, cb; + + sslctx_obj = (VALUE) arg; + cb = rb_iv_get(sslctx_obj, "@npn_select_cb"); + + return ssl_npn_select_cb_common(cb, (const unsigned char **)out, outlen, in, inlen); +} + #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB static int ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) { - int i = 0; - VALUE sslctx_obj, cb, protocols, selected; + VALUE sslctx_obj, cb; sslctx_obj = (VALUE) arg; cb = rb_iv_get(sslctx_obj, "@alpn_select_cb"); - protocols = rb_ary_new(); - - /* The format is len_1|proto_1|...|len_n|proto_n\0 */ - while (in[i]) { - VALUE protocol = rb_str_new((const char *) &in[i + 1], in[i]); - rb_ary_push(protocols, protocol); - i += in[i] + 1; - } - selected = rb_funcall(cb, rb_intern("call"), 1, protocols); - *out = (unsigned char *) StringValuePtr(selected); - *outlen = RSTRING_LENINT(selected); - - return SSL_TLSEXT_ERR_OK; + return ssl_npn_select_cb_common(cb, out, outlen, in, inlen); } #endif |