Merge branch 'vendor/PAM_PASSWDQC'
[dragonfly.git] / crypto / libressl / tls / tls_client.c
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 }