Lines 2186-2188
Link Here
|
2186 |
} |
2187 |
} |
2187 |
|
2188 |
|
2188 |
#endif /* OPENSSL_NO_SRP */ |
2189 |
#endif /* OPENSSL_NO_SRP */ |
|
|
2190 |
|
2191 |
#ifdef HAVE_TLS_NPN |
2192 |
/* |
2193 |
* This callback function is executed when SSL needs to decide what protocols |
2194 |
* to advertise during Next Protocol Negotiation (NPN). It must produce a |
2195 |
* string in wire format -- a sequence of length-prefixed strings -- indicating |
2196 |
* the advertised protocols. Refer to SSL_CTX_set_next_protos_advertised_cb |
2197 |
* in OpenSSL for reference. |
2198 |
*/ |
2199 |
int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out, |
2200 |
unsigned int *size_out, void *arg) |
2201 |
{ |
2202 |
conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); |
2203 |
apr_array_header_t *protos; |
2204 |
int num_protos; |
2205 |
unsigned int size; |
2206 |
int i; |
2207 |
unsigned char *data; |
2208 |
unsigned char *start; |
2209 |
|
2210 |
*data_out = NULL; |
2211 |
*size_out = 0; |
2212 |
|
2213 |
/* If the connection object is not available, then there's nothing for us |
2214 |
* to do. */ |
2215 |
if (c == NULL) { |
2216 |
return SSL_TLSEXT_ERR_OK; |
2217 |
} |
2218 |
|
2219 |
/* Invoke our npn_advertise_protos hook, giving other modules a chance to |
2220 |
* add alternate protocol names to advertise. */ |
2221 |
protos = apr_array_make(c->pool, 0, sizeof(char*)); |
2222 |
modssl_run_npn_advertise_protos_hook(c, protos); |
2223 |
num_protos = protos->nelts; |
2224 |
|
2225 |
/* We now have a list of null-terminated strings; we need to concatenate |
2226 |
* them together into a single string, where each protocol name is prefixed |
2227 |
* by its length. First, calculate how long that string will be. */ |
2228 |
size = 0; |
2229 |
for (i = 0; i < num_protos; ++i) { |
2230 |
const char *string = APR_ARRAY_IDX(protos, i, const char*); |
2231 |
apr_size_t length = strlen(string); |
2232 |
/* If the protocol name is too long (the length must fit in one byte), |
2233 |
* then log an error and skip it. */ |
2234 |
if (length > 255) { |
2235 |
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, |
2236 |
"SSL NPN protocol name too long (length=%u): %s", |
2237 |
length, string); |
2238 |
continue; |
2239 |
} |
2240 |
/* Leave room for the length prefix (one byte) plus the protocol name |
2241 |
* itself. */ |
2242 |
size += 1 + length; |
2243 |
} |
2244 |
|
2245 |
/* If there is nothing to advertise (either because no modules added |
2246 |
* anything to the protos array, or because all strings added to the array |
2247 |
* were skipped), then we're done. */ |
2248 |
if (size == 0) { |
2249 |
return SSL_TLSEXT_ERR_OK; |
2250 |
} |
2251 |
|
2252 |
/* Now we can build the string. Copy each protocol name string into the |
2253 |
* larger string, prefixed by its length. */ |
2254 |
data = apr_palloc(c->pool, size * sizeof(unsigned char)); |
2255 |
start = data; |
2256 |
for (i = 0; i < num_protos; ++i) { |
2257 |
const char *string = APR_ARRAY_IDX(protos, i, const char*); |
2258 |
apr_size_t length = strlen(string); |
2259 |
/* If the protocol name is too long then skip it. */ |
2260 |
if (length > 255) continue; |
2261 |
*start++ = (unsigned char)length; |
2262 |
memcpy(start, string, length * sizeof(unsigned char)); |
2263 |
start += length; |
2264 |
} |
2265 |
|
2266 |
/* Success. */ |
2267 |
*data_out = data; |
2268 |
*size_out = size; |
2269 |
return SSL_TLSEXT_ERR_OK; |
2270 |
} |
2271 |
#endif |