Lines 2109-2111
Link Here
|
2109 |
return 0; |
2109 |
return 0; |
2110 |
} |
2110 |
} |
2111 |
#endif |
2111 |
#endif |
|
|
2112 |
|
2113 |
#ifdef HAVE_TLS_NPN |
2114 |
/* |
2115 |
* This callback function is executed when SSL needs to decide what protocols |
2116 |
* to advertise during Next Protocol Negotiation (NPN). It must produce a |
2117 |
* string in wire format -- a sequence of length-prefixed strings -- indicating |
2118 |
* the advertised protocols. Refer to SSL_CTX_set_next_protos_advertised_cb |
2119 |
* in OpenSSL for reference. |
2120 |
*/ |
2121 |
int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out, |
2122 |
unsigned int *size_out, void *arg) |
2123 |
{ |
2124 |
conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); |
2125 |
apr_array_header_t *protos; |
2126 |
int num_protos; |
2127 |
unsigned int size; |
2128 |
int i; |
2129 |
unsigned char *data; |
2130 |
unsigned char *start; |
2131 |
|
2132 |
*data_out = NULL; |
2133 |
*size_out = 0; |
2134 |
|
2135 |
/* If the connection object is not available, then there's nothing for us |
2136 |
* to do. */ |
2137 |
if (c == NULL) { |
2138 |
return SSL_TLSEXT_ERR_OK; |
2139 |
} |
2140 |
|
2141 |
/* Invoke our npn_advertise_protos hook, giving other modules a chance to |
2142 |
* add alternate protocol names to advertise. */ |
2143 |
protos = apr_array_make(c->pool, 0, sizeof(char*)); |
2144 |
modssl_run_npn_advertise_protos_hook(c, protos); |
2145 |
num_protos = protos->nelts; |
2146 |
|
2147 |
/* We now have a list of null-terminated strings; we need to concatenate |
2148 |
* them together into a single string, where each protocol name is prefixed |
2149 |
* by its length. First, calculate how long that string will be. */ |
2150 |
size = 0; |
2151 |
for (i = 0; i < num_protos; ++i) { |
2152 |
const char *string = APR_ARRAY_IDX(protos, i, const char*); |
2153 |
apr_size_t length = strlen(string); |
2154 |
/* If the protocol name is too long (the length must fit in one byte), |
2155 |
* then log an error and skip it. */ |
2156 |
if (length > 255) { |
2157 |
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, |
2158 |
"SSL NPN protocol name too long (length=%u): %s", |
2159 |
length, string); |
2160 |
continue; |
2161 |
} |
2162 |
/* Leave room for the length prefix (one byte) plus the protocol name |
2163 |
* itself. */ |
2164 |
size += 1 + length; |
2165 |
} |
2166 |
|
2167 |
/* If there is nothing to advertise (either because no modules added |
2168 |
* anything to the protos array, or because all strings added to the array |
2169 |
* were skipped), then we're done. */ |
2170 |
if (size == 0) { |
2171 |
return SSL_TLSEXT_ERR_OK; |
2172 |
} |
2173 |
|
2174 |
/* Now we can build the string. Copy each protocol name string into the |
2175 |
* larger string, prefixed by its length. */ |
2176 |
data = apr_palloc(c->pool, size * sizeof(unsigned char)); |
2177 |
start = data; |
2178 |
for (i = 0; i < num_protos; ++i) { |
2179 |
const char *string = APR_ARRAY_IDX(protos, i, const char*); |
2180 |
apr_size_t length = strlen(string); |
2181 |
/* If the protocol name is too long then skip it. */ |
2182 |
if (length > 255) continue; |
2183 |
*start++ = (unsigned char)length; |
2184 |
memcpy(start, string, length * sizeof(unsigned char)); |
2185 |
start += length; |
2186 |
} |
2187 |
|
2188 |
/* Success. */ |
2189 |
*data_out = data; |
2190 |
*size_out = size; |
2191 |
return SSL_TLSEXT_ERR_OK; |
2192 |
} |
2193 |
#endif |