summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorinoguchi <>2020-07-27 13:06:13 +0000
committerinoguchi <>2020-07-27 13:06:13 +0000
commit76210d29c8ce23ac6f0db2610a1cef027179c7a0 (patch)
tree459bf9af208df69cc8014a2b8f9788ee6347e07e /src
parent407f7d98a914db77baf1ed3b08e34fc86b3e06bb (diff)
downloadopenbsd-76210d29c8ce23ac6f0db2610a1cef027179c7a0.tar.gz
openbsd-76210d29c8ce23ac6f0db2610a1cef027179c7a0.tar.bz2
openbsd-76210d29c8ce23ac6f0db2610a1cef027179c7a0.zip
Add function prototype and move sub functions to bottom
Diffstat (limited to 'src')
-rw-r--r--src/usr.bin/openssl/s_server.c395
1 files changed, 197 insertions, 198 deletions
diff --git a/src/usr.bin/openssl/s_server.c b/src/usr.bin/openssl/s_server.c
index ebabd41d3e..eb5f62ed56 100644
--- a/src/usr.bin/openssl/s_server.c
+++ b/src/usr.bin/openssl/s_server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s_server.c,v 1.41 2020/07/27 12:29:51 inoguchi Exp $ */ 1/* $OpenBSD: s_server.c,v 1.42 2020/07/27 13:06:13 inoguchi Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -177,21 +177,22 @@
177#include "s_apps.h" 177#include "s_apps.h"
178#include "timeouts.h" 178#include "timeouts.h"
179 179
180static void s_server_init(void);
181static void sv_usage(void);
182static void print_stats(BIO *bp, SSL_CTX *ctx);
180static int sv_body(char *hostname, int s, unsigned char *context); 183static int sv_body(char *hostname, int s, unsigned char *context);
181static int www_body(char *hostname, int s, unsigned char *context);
182static void close_accept_socket(void); 184static void close_accept_socket(void);
183static void sv_usage(void);
184static int init_ssl_connection(SSL *s); 185static int init_ssl_connection(SSL *s);
185static void print_stats(BIO *bp, SSL_CTX *ctx);
186static int
187generate_session_id(const SSL *ssl, unsigned char *id,
188 unsigned int *id_len);
189#ifndef OPENSSL_NO_DH 186#ifndef OPENSSL_NO_DH
190static DH *load_dh_param(const char *dhfile); 187static DH *load_dh_param(const char *dhfile);
191#endif 188#endif
192 189static int www_body(char *hostname, int s, unsigned char *context);
193static void s_server_init(void); 190static int generate_session_id(const SSL *ssl, unsigned char *id,
194 191 unsigned int *id_len);
192static int ssl_servername_cb(SSL *s, int *ad, void *arg);
193static int cert_status_cb(SSL * s, void *arg);
194static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
195 const unsigned char *in, unsigned int inlen, void *arg);
195/* static int load_CA(SSL_CTX *ctx, char *file);*/ 196/* static int load_CA(SSL_CTX *ctx, char *file);*/
196 197
197#define BUFSIZZ 16*1024 198#define BUFSIZZ 16*1024
@@ -205,7 +206,9 @@ static int s_server_session_id_context = 1; /* anything will do */
205static SSL_CTX *ctx = NULL; 206static SSL_CTX *ctx = NULL;
206static SSL_CTX *ctx2 = NULL; 207static SSL_CTX *ctx2 = NULL;
207static BIO *bio_s_out = NULL; 208static BIO *bio_s_out = NULL;
208static int cert_status_cb(SSL * s, void *arg); 209
210static int local_argc = 0;
211static char **local_argv;
209 212
210/* This is a context that we pass to callbacks */ 213/* This is a context that we pass to callbacks */
211typedef struct tlsextctx_st { 214typedef struct tlsextctx_st {
@@ -224,6 +227,12 @@ typedef struct tlsextstatusctx_st {
224 int verbose; 227 int verbose;
225} tlsextstatusctx; 228} tlsextstatusctx;
226 229
230/* This the context that we pass to alpn_cb */
231typedef struct tlsextalpnctx_st {
232 unsigned char *data;
233 unsigned short len;
234} tlsextalpnctx;
235
227static struct { 236static struct {
228 char *alpn_in; 237 char *alpn_in;
229 char *npn_in; /* Ignored. */ 238 char *npn_in; /* Ignored. */
@@ -1002,191 +1011,6 @@ sv_usage(void)
1002 fprintf(stderr, "\n"); 1011 fprintf(stderr, "\n");
1003} 1012}
1004 1013
1005static int local_argc = 0;
1006static char **local_argv;
1007
1008static int
1009ssl_servername_cb(SSL *s, int *ad, void *arg)
1010{
1011 tlsextctx *p = (tlsextctx *) arg;
1012 const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
1013 if (servername && p->biodebug)
1014 BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", servername);
1015
1016 if (!p->servername)
1017 return SSL_TLSEXT_ERR_NOACK;
1018
1019 if (servername) {
1020 if (strcmp(servername, p->servername))
1021 return p->extension_error;
1022 if (ctx2) {
1023 BIO_printf(p->biodebug, "Switching server context.\n");
1024 SSL_set_SSL_CTX(s, ctx2);
1025 }
1026 }
1027 return SSL_TLSEXT_ERR_OK;
1028}
1029
1030/* Certificate Status callback. This is called when a client includes a
1031 * certificate status request extension.
1032 *
1033 * This is a simplified version. It examines certificates each time and
1034 * makes one OCSP responder query for each request.
1035 *
1036 * A full version would store details such as the OCSP certificate IDs and
1037 * minimise the number of OCSP responses by caching them until they were
1038 * considered "expired".
1039 */
1040
1041static int
1042cert_status_cb(SSL *s, void *arg)
1043{
1044 tlsextstatusctx *srctx = arg;
1045 BIO *err = srctx->err;
1046 char *host = NULL, *port = NULL, *path = NULL;
1047 int use_ssl;
1048 unsigned char *rspder = NULL;
1049 int rspderlen;
1050 STACK_OF(OPENSSL_STRING) *aia = NULL;
1051 X509 *x = NULL;
1052 X509_STORE_CTX inctx;
1053 X509_OBJECT obj;
1054 OCSP_REQUEST *req = NULL;
1055 OCSP_RESPONSE *resp = NULL;
1056 OCSP_CERTID *id = NULL;
1057 STACK_OF(X509_EXTENSION) *exts;
1058 int ret = SSL_TLSEXT_ERR_NOACK;
1059 int i;
1060
1061 if (srctx->verbose)
1062 BIO_puts(err, "cert_status: callback called\n");
1063 /* Build up OCSP query from server certificate */
1064 x = SSL_get_certificate(s);
1065 aia = X509_get1_ocsp(x);
1066 if (aia) {
1067 if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
1068 &host, &port, &path, &use_ssl)) {
1069 BIO_puts(err, "cert_status: can't parse AIA URL\n");
1070 goto err;
1071 }
1072 if (srctx->verbose)
1073 BIO_printf(err, "cert_status: AIA URL: %s\n",
1074 sk_OPENSSL_STRING_value(aia, 0));
1075 } else {
1076 if (!srctx->host) {
1077 BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
1078 goto done;
1079 }
1080 host = srctx->host;
1081 path = srctx->path;
1082 port = srctx->port;
1083 use_ssl = srctx->use_ssl;
1084 }
1085
1086 if (!X509_STORE_CTX_init(&inctx,
1087 SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
1088 NULL, NULL))
1089 goto err;
1090 if (X509_STORE_get_by_subject(&inctx, X509_LU_X509,
1091 X509_get_issuer_name(x), &obj) <= 0) {
1092 BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
1093 X509_STORE_CTX_cleanup(&inctx);
1094 goto done;
1095 }
1096 req = OCSP_REQUEST_new();
1097 if (!req)
1098 goto err;
1099 id = OCSP_cert_to_id(NULL, x, obj.data.x509);
1100 X509_free(obj.data.x509);
1101 X509_STORE_CTX_cleanup(&inctx);
1102 if (!id)
1103 goto err;
1104 if (!OCSP_request_add0_id(req, id))
1105 goto err;
1106 id = NULL;
1107 /* Add any extensions to the request */
1108 SSL_get_tlsext_status_exts(s, &exts);
1109 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
1110 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
1111 if (!OCSP_REQUEST_add_ext(req, ext, -1))
1112 goto err;
1113 }
1114 resp = process_responder(err, req, host, path, port, use_ssl, NULL,
1115 srctx->timeout);
1116 if (!resp) {
1117 BIO_puts(err, "cert_status: error querying responder\n");
1118 goto done;
1119 }
1120 rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
1121 if (rspderlen <= 0)
1122 goto err;
1123 SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
1124 if (srctx->verbose) {
1125 BIO_puts(err, "cert_status: ocsp response sent:\n");
1126 OCSP_RESPONSE_print(err, resp, 2);
1127 }
1128 ret = SSL_TLSEXT_ERR_OK;
1129 done:
1130 if (ret != SSL_TLSEXT_ERR_OK)
1131 ERR_print_errors(err);
1132 if (aia) {
1133 free(host);
1134 free(path);
1135 free(port);
1136 X509_email_free(aia);
1137 }
1138 if (id)
1139 OCSP_CERTID_free(id);
1140 if (req)
1141 OCSP_REQUEST_free(req);
1142 if (resp)
1143 OCSP_RESPONSE_free(resp);
1144 return ret;
1145 err:
1146 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
1147 goto done;
1148}
1149
1150/* This the context that we pass to alpn_cb */
1151typedef struct tlsextalpnctx_st {
1152 unsigned char *data;
1153 unsigned short len;
1154} tlsextalpnctx;
1155
1156static int
1157alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
1158 const unsigned char *in, unsigned int inlen, void *arg)
1159{
1160 tlsextalpnctx *alpn_ctx = arg;
1161
1162 if (!s_server_config.quiet) {
1163 /* We can assume that in is syntactically valid. */
1164 unsigned i;
1165
1166 BIO_printf(bio_s_out,
1167 "ALPN protocols advertised by the client: ");
1168 for (i = 0; i < inlen; ) {
1169 if (i)
1170 BIO_write(bio_s_out, ", ", 2);
1171 BIO_write(bio_s_out, &in[i + 1], in[i]);
1172 i += in[i] + 1;
1173 }
1174 BIO_write(bio_s_out, "\n", 1);
1175 }
1176
1177 if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data,
1178 alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED)
1179 return (SSL_TLSEXT_ERR_NOACK);
1180
1181 if (!s_server_config.quiet) {
1182 BIO_printf(bio_s_out, "ALPN protocols selected: ");
1183 BIO_write(bio_s_out, *out, *outlen);
1184 BIO_write(bio_s_out, "\n", 1);
1185 }
1186
1187 return (SSL_TLSEXT_ERR_OK);
1188}
1189
1190int 1014int
1191s_server_main(int argc, char *argv[]) 1015s_server_main(int argc, char *argv[])
1192{ 1016{
@@ -2343,8 +2167,7 @@ www_body(char *hostname, int s, unsigned char *context)
2343 2167
2344#define MAX_SESSION_ID_ATTEMPTS 10 2168#define MAX_SESSION_ID_ATTEMPTS 10
2345static int 2169static int
2346generate_session_id(const SSL *ssl, unsigned char *id, 2170generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len)
2347 unsigned int *id_len)
2348{ 2171{
2349 unsigned int count = 0; 2172 unsigned int count = 0;
2350 do { 2173 do {
@@ -2366,3 +2189,179 @@ generate_session_id(const SSL *ssl, unsigned char *id,
2366 return 0; 2189 return 0;
2367 return 1; 2190 return 1;
2368} 2191}
2192
2193static int
2194ssl_servername_cb(SSL *s, int *ad, void *arg)
2195{
2196 tlsextctx *p = (tlsextctx *) arg;
2197 const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
2198 if (servername && p->biodebug)
2199 BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n", servername);
2200
2201 if (!p->servername)
2202 return SSL_TLSEXT_ERR_NOACK;
2203
2204 if (servername) {
2205 if (strcmp(servername, p->servername))
2206 return p->extension_error;
2207 if (ctx2) {
2208 BIO_printf(p->biodebug, "Switching server context.\n");
2209 SSL_set_SSL_CTX(s, ctx2);
2210 }
2211 }
2212 return SSL_TLSEXT_ERR_OK;
2213}
2214
2215/* Certificate Status callback. This is called when a client includes a
2216 * certificate status request extension.
2217 *
2218 * This is a simplified version. It examines certificates each time and
2219 * makes one OCSP responder query for each request.
2220 *
2221 * A full version would store details such as the OCSP certificate IDs and
2222 * minimise the number of OCSP responses by caching them until they were
2223 * considered "expired".
2224 */
2225
2226static int
2227cert_status_cb(SSL *s, void *arg)
2228{
2229 tlsextstatusctx *srctx = arg;
2230 BIO *err = srctx->err;
2231 char *host = NULL, *port = NULL, *path = NULL;
2232 int use_ssl;
2233 unsigned char *rspder = NULL;
2234 int rspderlen;
2235 STACK_OF(OPENSSL_STRING) *aia = NULL;
2236 X509 *x = NULL;
2237 X509_STORE_CTX inctx;
2238 X509_OBJECT obj;
2239 OCSP_REQUEST *req = NULL;
2240 OCSP_RESPONSE *resp = NULL;
2241 OCSP_CERTID *id = NULL;
2242 STACK_OF(X509_EXTENSION) *exts;
2243 int ret = SSL_TLSEXT_ERR_NOACK;
2244 int i;
2245
2246 if (srctx->verbose)
2247 BIO_puts(err, "cert_status: callback called\n");
2248 /* Build up OCSP query from server certificate */
2249 x = SSL_get_certificate(s);
2250 aia = X509_get1_ocsp(x);
2251 if (aia) {
2252 if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
2253 &host, &port, &path, &use_ssl)) {
2254 BIO_puts(err, "cert_status: can't parse AIA URL\n");
2255 goto err;
2256 }
2257 if (srctx->verbose)
2258 BIO_printf(err, "cert_status: AIA URL: %s\n",
2259 sk_OPENSSL_STRING_value(aia, 0));
2260 } else {
2261 if (!srctx->host) {
2262 BIO_puts(srctx->err, "cert_status: no AIA and no default responder URL\n");
2263 goto done;
2264 }
2265 host = srctx->host;
2266 path = srctx->path;
2267 port = srctx->port;
2268 use_ssl = srctx->use_ssl;
2269 }
2270
2271 if (!X509_STORE_CTX_init(&inctx,
2272 SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
2273 NULL, NULL))
2274 goto err;
2275 if (X509_STORE_get_by_subject(&inctx, X509_LU_X509,
2276 X509_get_issuer_name(x), &obj) <= 0) {
2277 BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
2278 X509_STORE_CTX_cleanup(&inctx);
2279 goto done;
2280 }
2281 req = OCSP_REQUEST_new();
2282 if (!req)
2283 goto err;
2284 id = OCSP_cert_to_id(NULL, x, obj.data.x509);
2285 X509_free(obj.data.x509);
2286 X509_STORE_CTX_cleanup(&inctx);
2287 if (!id)
2288 goto err;
2289 if (!OCSP_request_add0_id(req, id))
2290 goto err;
2291 id = NULL;
2292 /* Add any extensions to the request */
2293 SSL_get_tlsext_status_exts(s, &exts);
2294 for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
2295 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
2296 if (!OCSP_REQUEST_add_ext(req, ext, -1))
2297 goto err;
2298 }
2299 resp = process_responder(err, req, host, path, port, use_ssl, NULL,
2300 srctx->timeout);
2301 if (!resp) {
2302 BIO_puts(err, "cert_status: error querying responder\n");
2303 goto done;
2304 }
2305 rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
2306 if (rspderlen <= 0)
2307 goto err;
2308 SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
2309 if (srctx->verbose) {
2310 BIO_puts(err, "cert_status: ocsp response sent:\n");
2311 OCSP_RESPONSE_print(err, resp, 2);
2312 }
2313 ret = SSL_TLSEXT_ERR_OK;
2314 done:
2315 if (ret != SSL_TLSEXT_ERR_OK)
2316 ERR_print_errors(err);
2317 if (aia) {
2318 free(host);
2319 free(path);
2320 free(port);
2321 X509_email_free(aia);
2322 }
2323 if (id)
2324 OCSP_CERTID_free(id);
2325 if (req)
2326 OCSP_REQUEST_free(req);
2327 if (resp)
2328 OCSP_RESPONSE_free(resp);
2329 return ret;
2330 err:
2331 ret = SSL_TLSEXT_ERR_ALERT_FATAL;
2332 goto done;
2333}
2334
2335static int
2336alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
2337 const unsigned char *in, unsigned int inlen, void *arg)
2338{
2339 tlsextalpnctx *alpn_ctx = arg;
2340
2341 if (!s_server_config.quiet) {
2342 /* We can assume that in is syntactically valid. */
2343 unsigned i;
2344
2345 BIO_printf(bio_s_out,
2346 "ALPN protocols advertised by the client: ");
2347 for (i = 0; i < inlen; ) {
2348 if (i)
2349 BIO_write(bio_s_out, ", ", 2);
2350 BIO_write(bio_s_out, &in[i + 1], in[i]);
2351 i += in[i] + 1;
2352 }
2353 BIO_write(bio_s_out, "\n", 1);
2354 }
2355
2356 if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data,
2357 alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED)
2358 return (SSL_TLSEXT_ERR_NOACK);
2359
2360 if (!s_server_config.quiet) {
2361 BIO_printf(bio_s_out, "ALPN protocols selected: ");
2362 BIO_write(bio_s_out, *out, *outlen);
2363 BIO_write(bio_s_out, "\n", 1);
2364 }
2365
2366 return (SSL_TLSEXT_ERR_OK);
2367}