aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_ssl.c
diff options
context:
space:
mode:
authorZachary Scott <e@zzak.io>2015-11-13 11:02:30 +0900
committerZachary Scott <e@zzak.io>2015-11-13 11:10:06 +0900
commitcc36e11b6621281e2f3e700a1b38327adcff2b71 (patch)
tree07ff07acd6797c66a3c599a90c840206e5c81791 /ext/openssl/ossl_ssl.c
parent908a62cc0cff25f1861fcb69b70e10a31590e3d2 (diff)
downloadruby-openssl-cc36e11b6621281e2f3e700a1b38327adcff2b71.tar.gz
Merge trunk upstream
Diffstat (limited to 'ext/openssl/ossl_ssl.c')
-rw-r--r--ext/openssl/ossl_ssl.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 3e6e1646..09d8dd24 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -581,53 +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++) != '\0') {
+ 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);
- *out = (unsigned char *) StringValuePtr(selected);
- *outlen = RSTRING_LENINT(selected);
+ len = RSTRING_LEN(selected);
+ if (len < 1 || len >= 256) {
+ ossl_raise(eSSLError, "Selected protocol name must have length 1..255");
+ }
+ *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
@@ -696,7 +701,8 @@ ossl_sslctx_setup(VALUE self)
X509_STORE *store;
EVP_PKEY *key = NULL;
char *ca_path = NULL, *ca_file = NULL;
- int i, verify_mode;
+ int verify_mode;
+ long i;
VALUE val;
if(OBJ_FROZEN(self)) return Qnil;
@@ -753,7 +759,7 @@ ossl_sslctx_setup(VALUE self)
if(!NIL_P(val)){
if (RB_TYPE_P(val, T_ARRAY)) {
for(i = 0; i < RARRAY_LEN(val); i++){
- client_ca = GetX509CertPtr(RARRAY_PTR(val)[i]);
+ client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
if (!SSL_CTX_add_client_CA(ctx, client_ca)){
/* Copies X509_NAME => FREE it. */
ossl_raise(eSSLError, "SSL_CTX_add_client_CA");