xref: /dragonfly/crypto/libressl/tls/tls_client.c (revision 73b5ca6b)
1 /* $OpenBSD: tls_client.c,v 1.45 2018/03/19 16:34:47 jsing Exp $ */
2 /*
3  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/stat.h>
21 
22 #include <arpa/inet.h>
23 #include <netinet/in.h>
24 
25 #include <limits.h>
26 #include <netdb.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 
30 #include <openssl/err.h>
31 #include <openssl/x509.h>
32 
33 #include <tls.h>
34 #include "tls_internal.h"
35 
36 struct tls *
37 tls_client(void)
38 {
39 	struct tls *ctx;
40 
41 	if (tls_init() == -1)
42 		return (NULL);
43 
44 	if ((ctx = tls_new()) == NULL)
45 		return (NULL);
46 
47 	ctx->flags |= TLS_CLIENT;
48 
49 	return (ctx);
50 }
51 
52 int
53 tls_connect(struct tls *ctx, const char *host, const char *port)
54 {
55 	return tls_connect_servername(ctx, host, port, NULL);
56 }
57 
58 int
59 tls_connect_servername(struct tls *ctx, const char *host, const char *port,
60     const char *servername)
61 {
62 	struct addrinfo hints, *res, *res0;
63 	const char *h = NULL, *p = NULL;
64 	char *hs = NULL, *ps = NULL;
65 	int rv = -1, s = -1, ret;
66 
67 	if ((ctx->flags & TLS_CLIENT) == 0) {
68 		tls_set_errorx(ctx, "not a client context");
69 		goto err;
70 	}
71 
72 	if (host == NULL) {
73 		tls_set_errorx(ctx, "host not specified");
74 		goto err;
75 	}
76 
77 	/*
78 	 * If port is NULL try to extract a port from the specified host,
79 	 * otherwise use the default.
80 	 */
81 	if ((p = (char *)port) == NULL) {
82 		ret = tls_host_port(host, &hs, &ps);
83 		if (ret == -1) {
84 			tls_set_errorx(ctx, "memory allocation failure");
85 			goto err;
86 		}
87 		if (ret != 0) {
88 			tls_set_errorx(ctx, "no port provided");
89 			goto err;
90 		}
91 	}
92 
93 	h = (hs != NULL) ? hs : host;
94 	p = (ps != NULL) ? ps : port;
95 
96 	/*
97 	 * First check if the host is specified as a numeric IP address,
98 	 * either IPv4 or IPv6, before trying to resolve the host.
99 	 * The AI_ADDRCONFIG resolver option will not return IPv4 or IPv6
100 	 * records if it is not configured on an interface;  not considering
101 	 * loopback addresses.  Checking the numeric addresses first makes
102 	 * sure that connection attempts to numeric addresses and especially
103 	 * 127.0.0.1 or ::1 loopback addresses are always possible.
104 	 */
105 	memset(&hints, 0, sizeof(hints));
106 	hints.ai_socktype = SOCK_STREAM;
107 
108 	/* try as an IPv4 literal */
109 	hints.ai_family = AF_INET;
110 	hints.ai_flags = AI_NUMERICHOST;
111 	if (getaddrinfo(h, p, &hints, &res0) != 0) {
112 		/* try again as an IPv6 literal */
113 		hints.ai_family = AF_INET6;
114 		if (getaddrinfo(h, p, &hints, &res0) != 0) {
115 			/* last try, with name resolution and save the error */
116 			hints.ai_family = AF_UNSPEC;
117 			hints.ai_flags = AI_ADDRCONFIG;
118 			if ((s = getaddrinfo(h, p, &hints, &res0)) != 0) {
119 				tls_set_error(ctx, "%s", gai_strerror(s));
120 				goto err;
121 			}
122 		}
123 	}
124 
125 	/* It was resolved somehow; now try connecting to what we got */
126 	s = -1;
127 	for (res = res0; res; res = res->ai_next) {
128 		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
129 		if (s == -1) {
130 			tls_set_error(ctx, "socket");
131 			continue;
132 		}
133 		if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
134 			tls_set_error(ctx, "connect");
135 			close(s);
136 			s = -1;
137 			continue;
138 		}
139 
140 		break;  /* Connected. */
141 	}
142 	freeaddrinfo(res0);
143 
144 	if (s == -1)
145 		goto err;
146 
147 	if (servername == NULL)
148 		servername = h;
149 
150 	if (tls_connect_socket(ctx, s, servername) != 0) {
151 		close(s);
152 		goto err;
153 	}
154 
155 	ctx->socket = s;
156 
157 	rv = 0;
158 
159  err:
160 	free(hs);
161 	free(ps);
162 
163 	return (rv);
164 }
165 
166 static int
167 tls_client_read_session(struct tls *ctx)
168 {
169 	int sfd = ctx->config->session_fd;
170 	uint8_t *session = NULL;
171 	size_t session_len = 0;
172 	SSL_SESSION *ss = NULL;
173 	BIO *bio = NULL;
174 	struct stat sb;
175 	ssize_t n;
176 	int rv = -1;
177 
178 	if (fstat(sfd, &sb) == -1) {
179 		tls_set_error(ctx, "failed to stat session file");
180 		goto err;
181 	}
182 	if (sb.st_size < 0 || sb.st_size > INT_MAX) {
183 		tls_set_errorx(ctx, "invalid session file size");
184 		goto err;
185 	}
186 	session_len = (size_t)sb.st_size;
187 
188 	/* A zero size file means that we do not yet have a valid session. */
189 	if (session_len == 0)
190 		goto done;
191 
192 	if ((session = malloc(session_len)) == NULL)
193 		goto err;
194 
195 	n = pread(sfd, session, session_len, 0);
196 	if (n < 0 || (size_t)n != session_len) {
197 		tls_set_error(ctx, "failed to read session file");
198 		goto err;
199 	}
200 	if ((bio = BIO_new_mem_buf(session, session_len)) == NULL)
201 		goto err;
202 	if ((ss = PEM_read_bio_SSL_SESSION(bio, NULL, tls_password_cb,
203 	    NULL)) == NULL) {
204 		tls_set_errorx(ctx, "failed to parse session");
205 		goto err;
206 	}
207 
208 	if (SSL_set_session(ctx->ssl_conn, ss) != 1) {
209 		tls_set_errorx(ctx, "failed to set session");
210 		goto err;
211 	}
212 
213  done:
214 	rv = 0;
215 
216  err:
217 	freezero(session, session_len);
218 	SSL_SESSION_free(ss);
219 	BIO_free(bio);
220 
221 	return rv;
222 }
223 
224 static int
225 tls_client_write_session(struct tls *ctx)
226 {
227 	int sfd = ctx->config->session_fd;
228 	SSL_SESSION *ss = NULL;
229 	BIO *bio = NULL;
230 	long data_len;
231 	char *data;
232 	off_t offset;
233 	size_t len;
234 	ssize_t n;
235 	int rv = -1;
236 
237 	if ((ss = SSL_get1_session(ctx->ssl_conn)) == NULL) {
238 		if (ftruncate(sfd, 0) == -1) {
239 			tls_set_error(ctx, "failed to truncate session file");
240 			goto err;
241 		}
242 		goto done;
243 	}
244 
245 	if ((bio = BIO_new(BIO_s_mem())) == NULL)
246 		goto err;
247 	if (PEM_write_bio_SSL_SESSION(bio, ss) == 0)
248 		goto err;
249 	if ((data_len = BIO_get_mem_data(bio, &data)) <= 0)
250 		goto err;
251 
252 	len = (size_t)data_len;
253 	offset = 0;
254 
255 	if (ftruncate(sfd, len) == -1) {
256 		tls_set_error(ctx, "failed to truncate session file");
257 		goto err;
258 	}
259 	while (len > 0) {
260 		if ((n = pwrite(sfd, data + offset, len, offset)) == -1) {
261 			tls_set_error(ctx, "failed to write session file");
262 			goto err;
263 		}
264 		offset += n;
265 		len -= n;
266 	}
267 
268  done:
269 	rv = 0;
270 
271  err:
272 	SSL_SESSION_free(ss);
273 	BIO_free_all(bio);
274 
275 	return (rv);
276 }
277 
278 static int
279 tls_connect_common(struct tls *ctx, const char *servername)
280 {
281 	union tls_addr addrbuf;
282 	int rv = -1;
283 
284 	if ((ctx->flags & TLS_CLIENT) == 0) {
285 		tls_set_errorx(ctx, "not a client context");
286 		goto err;
287 	}
288 
289 	if (servername != NULL) {
290 		if ((ctx->servername = strdup(servername)) == NULL) {
291 			tls_set_errorx(ctx, "out of memory");
292 			goto err;
293 		}
294 	}
295 
296 	if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
297 		tls_set_errorx(ctx, "ssl context failure");
298 		goto err;
299 	}
300 
301 	if (tls_configure_ssl(ctx, ctx->ssl_ctx) != 0)
302 		goto err;
303 
304 	if (tls_configure_ssl_keypair(ctx, ctx->ssl_ctx,
305 	    ctx->config->keypair, 0) != 0)
306 		goto err;
307 
308 	if (ctx->config->verify_name) {
309 		if (servername == NULL) {
310 			tls_set_errorx(ctx, "server name not specified");
311 			goto err;
312 		}
313 	}
314 
315 	if (tls_configure_ssl_verify(ctx, ctx->ssl_ctx, SSL_VERIFY_PEER) == -1)
316 		goto err;
317 
318 	if (ctx->config->ecdhecurves != NULL) {
319 		if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves,
320 		    ctx->config->ecdhecurves_len) != 1) {
321 			tls_set_errorx(ctx, "failed to set ecdhe curves");
322 			goto err;
323 		}
324 	}
325 
326 	if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) {
327 		tls_set_errorx(ctx, "ssl OCSP verification setup failure");
328 		goto err;
329 	}
330 
331 	if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
332 		tls_set_errorx(ctx, "ssl connection failure");
333 		goto err;
334 	}
335 
336 	if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) {
337 		tls_set_errorx(ctx, "ssl application data failure");
338 		goto err;
339 	}
340 
341 	if (ctx->config->session_fd != -1) {
342 		SSL_clear_options(ctx->ssl_conn, SSL_OP_NO_TICKET);
343 		if (tls_client_read_session(ctx) == -1)
344 			goto err;
345 	}
346 
347 	if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) {
348 		tls_set_errorx(ctx, "ssl OCSP extension setup failure");
349 		goto err;
350 	}
351 
352 	/*
353 	 * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not
354 	 * permitted in "HostName".
355 	 */
356 	if (servername != NULL &&
357 	    inet_pton(AF_INET, servername, &addrbuf) != 1 &&
358 	    inet_pton(AF_INET6, servername, &addrbuf) != 1) {
359 		if (SSL_set_tlsext_host_name(ctx->ssl_conn, servername) == 0) {
360 			tls_set_errorx(ctx, "server name indication failure");
361 			goto err;
362 		}
363 	}
364 
365 	ctx->state |= TLS_CONNECTED;
366 	rv = 0;
367 
368  err:
369 	return (rv);
370 }
371 
372 int
373 tls_connect_socket(struct tls *ctx, int s, const char *servername)
374 {
375 	return tls_connect_fds(ctx, s, s, servername);
376 }
377 
378 int
379 tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
380     const char *servername)
381 {
382 	int rv = -1;
383 
384 	if (fd_read < 0 || fd_write < 0) {
385 		tls_set_errorx(ctx, "invalid file descriptors");
386 		goto err;
387 	}
388 
389 	if (tls_connect_common(ctx, servername) != 0)
390 		goto err;
391 
392 	if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 ||
393 	    SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) {
394 		tls_set_errorx(ctx, "ssl file descriptor failure");
395 		goto err;
396 	}
397 
398 	rv = 0;
399  err:
400 	return (rv);
401 }
402 
403 int
404 tls_connect_cbs(struct tls *ctx, tls_read_cb read_cb,
405     tls_write_cb write_cb, void *cb_arg, const char *servername)
406 {
407 	int rv = -1;
408 
409 	if (tls_connect_common(ctx, servername) != 0)
410 		goto err;
411 
412 	if (tls_set_cbs(ctx, read_cb, write_cb, cb_arg) != 0)
413 		goto err;
414 
415 	rv = 0;
416 
417  err:
418 	return (rv);
419 }
420 
421 int
422 tls_handshake_client(struct tls *ctx)
423 {
424 	X509 *cert = NULL;
425 	int match, ssl_ret;
426 	int rv = -1;
427 
428 	if ((ctx->flags & TLS_CLIENT) == 0) {
429 		tls_set_errorx(ctx, "not a client context");
430 		goto err;
431 	}
432 
433 	if ((ctx->state & TLS_CONNECTED) == 0) {
434 		tls_set_errorx(ctx, "context not connected");
435 		goto err;
436 	}
437 
438 	ctx->state |= TLS_SSL_NEEDS_SHUTDOWN;
439 
440 	ERR_clear_error();
441 	if ((ssl_ret = SSL_connect(ctx->ssl_conn)) != 1) {
442 		rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake");
443 		goto err;
444 	}
445 
446 	if (ctx->config->verify_name) {
447 		cert = SSL_get_peer_certificate(ctx->ssl_conn);
448 		if (cert == NULL) {
449 			tls_set_errorx(ctx, "no server certificate");
450 			goto err;
451 		}
452 		if (tls_check_name(ctx, cert, ctx->servername, &match) == -1)
453 			goto err;
454 		if (!match) {
455 			tls_set_errorx(ctx, "name `%s' not present in"
456 			    " server certificate", ctx->servername);
457 			goto err;
458 		}
459 	}
460 
461 	ctx->state |= TLS_HANDSHAKE_COMPLETE;
462 
463 	if (ctx->config->session_fd != -1) {
464 		if (tls_client_write_session(ctx) == -1)
465 			goto err;
466 	}
467 
468 	rv = 0;
469 
470  err:
471 	X509_free(cert);
472 
473 	return (rv);
474 }
475