Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/libressl/src/tls/tls_client.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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)
| 0-30 | ||||||||||||||||||||||||||||||
42 | return (NULL); never executed: return ( ((void *)0) ); | 0 | ||||||||||||||||||||||||||||||
43 | - | |||||||||||||||||||||||||||||||
44 | if ((ctx = tls_new()) == NULL)
| 0-30 | ||||||||||||||||||||||||||||||
45 | return (NULL); never executed: return ( ((void *)0) ); | 0 | ||||||||||||||||||||||||||||||
46 | - | |||||||||||||||||||||||||||||||
47 | ctx->flags |= TLS_CLIENT; | - | ||||||||||||||||||||||||||||||
48 | - | |||||||||||||||||||||||||||||||
49 | return (ctx); executed 30 times by 2 tests: return (ctx); Executed by:
| 30 | ||||||||||||||||||||||||||||||
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); never executed: return tls_connect_servername(ctx, host, port, ((void *)0) ); | 0 | ||||||||||||||||||||||||||||||
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) {
| 0 | ||||||||||||||||||||||||||||||
68 | tls_set_errorx(ctx, "not a client context"); | - | ||||||||||||||||||||||||||||||
69 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
70 | } | - | ||||||||||||||||||||||||||||||
71 | - | |||||||||||||||||||||||||||||||
72 | if (host == NULL) {
| 0 | ||||||||||||||||||||||||||||||
73 | tls_set_errorx(ctx, "host not specified"); | - | ||||||||||||||||||||||||||||||
74 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
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) {
| 0 | ||||||||||||||||||||||||||||||
82 | ret = tls_host_port(host, &hs, &ps); | - | ||||||||||||||||||||||||||||||
83 | if (ret == -1) {
| 0 | ||||||||||||||||||||||||||||||
84 | tls_set_errorx(ctx, "memory allocation failure"); | - | ||||||||||||||||||||||||||||||
85 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
86 | } | - | ||||||||||||||||||||||||||||||
87 | if (ret != 0) {
| 0 | ||||||||||||||||||||||||||||||
88 | tls_set_errorx(ctx, "no port provided"); | - | ||||||||||||||||||||||||||||||
89 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
90 | } | - | ||||||||||||||||||||||||||||||
91 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
92 | - | |||||||||||||||||||||||||||||||
93 | h = (hs != NULL) ? hs : host;
| 0 | ||||||||||||||||||||||||||||||
94 | p = (ps != NULL) ? ps : port;
| 0 | ||||||||||||||||||||||||||||||
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) {
| 0 | ||||||||||||||||||||||||||||||
112 | /* try again as an IPv6 literal */ | - | ||||||||||||||||||||||||||||||
113 | hints.ai_family = AF_INET6; | - | ||||||||||||||||||||||||||||||
114 | if (getaddrinfo(h, p, &hints, &res0) != 0) {
| 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) {
| 0 | ||||||||||||||||||||||||||||||
119 | tls_set_error(ctx, "%s", gai_strerror(s)); | - | ||||||||||||||||||||||||||||||
120 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
121 | } | - | ||||||||||||||||||||||||||||||
122 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
123 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
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) {
| 0 | ||||||||||||||||||||||||||||||
128 | s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | - | ||||||||||||||||||||||||||||||
129 | if (s == -1) {
| 0 | ||||||||||||||||||||||||||||||
130 | tls_set_error(ctx, "socket"); | - | ||||||||||||||||||||||||||||||
131 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||||||||
132 | } | - | ||||||||||||||||||||||||||||||
133 | if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
| 0 | ||||||||||||||||||||||||||||||
134 | tls_set_error(ctx, "connect"); | - | ||||||||||||||||||||||||||||||
135 | close(s); | - | ||||||||||||||||||||||||||||||
136 | s = -1; | - | ||||||||||||||||||||||||||||||
137 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||||||||
138 | } | - | ||||||||||||||||||||||||||||||
139 | - | |||||||||||||||||||||||||||||||
140 | break; /* Connected. */ never executed: break; | 0 | ||||||||||||||||||||||||||||||
141 | } | - | ||||||||||||||||||||||||||||||
142 | freeaddrinfo(res0); | - | ||||||||||||||||||||||||||||||
143 | - | |||||||||||||||||||||||||||||||
144 | if (s == -1)
| 0 | ||||||||||||||||||||||||||||||
145 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
146 | - | |||||||||||||||||||||||||||||||
147 | if (servername == NULL)
| 0 | ||||||||||||||||||||||||||||||
148 | servername = h; never executed: servername = h; | 0 | ||||||||||||||||||||||||||||||
149 | - | |||||||||||||||||||||||||||||||
150 | if (tls_connect_socket(ctx, s, servername) != 0) {
| 0 | ||||||||||||||||||||||||||||||
151 | close(s); | - | ||||||||||||||||||||||||||||||
152 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
153 | } | - | ||||||||||||||||||||||||||||||
154 | - | |||||||||||||||||||||||||||||||
155 | ctx->socket = s; | - | ||||||||||||||||||||||||||||||
156 | - | |||||||||||||||||||||||||||||||
157 | rv = 0; | - | ||||||||||||||||||||||||||||||
158 | - | |||||||||||||||||||||||||||||||
159 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||||||||
160 | free(hs); | - | ||||||||||||||||||||||||||||||
161 | free(ps); | - | ||||||||||||||||||||||||||||||
162 | - | |||||||||||||||||||||||||||||||
163 | return (rv); never executed: return (rv); | 0 | ||||||||||||||||||||||||||||||
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) {
| 0 | ||||||||||||||||||||||||||||||
179 | tls_set_error(ctx, "failed to stat session file"); | - | ||||||||||||||||||||||||||||||
180 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
181 | } | - | ||||||||||||||||||||||||||||||
182 | if (sb.st_size < 0 || sb.st_size > INT_MAX) {
| 0 | ||||||||||||||||||||||||||||||
183 | tls_set_errorx(ctx, "invalid session file size"); | - | ||||||||||||||||||||||||||||||
184 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
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)
| 0 | ||||||||||||||||||||||||||||||
190 | goto done; never executed: goto done; | 0 | ||||||||||||||||||||||||||||||
191 | - | |||||||||||||||||||||||||||||||
192 | if ((session = malloc(session_len)) == NULL)
| 0 | ||||||||||||||||||||||||||||||
193 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
194 | - | |||||||||||||||||||||||||||||||
195 | n = pread(sfd, session, session_len, 0); | - | ||||||||||||||||||||||||||||||
196 | if (n < 0 || (size_t)n != session_len) {
| 0 | ||||||||||||||||||||||||||||||
197 | tls_set_error(ctx, "failed to read session file"); | - | ||||||||||||||||||||||||||||||
198 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
199 | } | - | ||||||||||||||||||||||||||||||
200 | if ((bio = BIO_new_mem_buf(session, session_len)) == NULL)
| 0 | ||||||||||||||||||||||||||||||
201 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
202 | if ((ss = PEM_read_bio_SSL_SESSION(bio, NULL, tls_password_cb,
| 0 | ||||||||||||||||||||||||||||||
203 | NULL)) == NULL) {
| 0 | ||||||||||||||||||||||||||||||
204 | tls_set_errorx(ctx, "failed to parse session"); | - | ||||||||||||||||||||||||||||||
205 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
206 | } | - | ||||||||||||||||||||||||||||||
207 | - | |||||||||||||||||||||||||||||||
208 | if (SSL_set_session(ctx->ssl_conn, ss) != 1) {
| 0 | ||||||||||||||||||||||||||||||
209 | tls_set_errorx(ctx, "failed to set session"); | - | ||||||||||||||||||||||||||||||
210 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
211 | } | - | ||||||||||||||||||||||||||||||
212 | - | |||||||||||||||||||||||||||||||
213 | done: code before this statement never executed: done: | 0 | ||||||||||||||||||||||||||||||
214 | rv = 0; | - | ||||||||||||||||||||||||||||||
215 | - | |||||||||||||||||||||||||||||||
216 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||||||||
217 | freezero(session, session_len); | - | ||||||||||||||||||||||||||||||
218 | SSL_SESSION_free(ss); | - | ||||||||||||||||||||||||||||||
219 | BIO_free(bio); | - | ||||||||||||||||||||||||||||||
220 | - | |||||||||||||||||||||||||||||||
221 | return rv; never executed: return rv; | 0 | ||||||||||||||||||||||||||||||
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) {
| 0 | ||||||||||||||||||||||||||||||
238 | if (ftruncate(sfd, 0) == -1) {
| 0 | ||||||||||||||||||||||||||||||
239 | tls_set_error(ctx, "failed to truncate session file"); | - | ||||||||||||||||||||||||||||||
240 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
241 | } | - | ||||||||||||||||||||||||||||||
242 | goto done; never executed: goto done; | 0 | ||||||||||||||||||||||||||||||
243 | } | - | ||||||||||||||||||||||||||||||
244 | - | |||||||||||||||||||||||||||||||
245 | if ((bio = BIO_new(BIO_s_mem())) == NULL)
| 0 | ||||||||||||||||||||||||||||||
246 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
247 | if (PEM_write_bio_SSL_SESSION(bio, ss) == 0)
| 0 | ||||||||||||||||||||||||||||||
248 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
249 | if ((data_len = BIO_get_mem_data(bio, &data)) <= 0)
| 0 | ||||||||||||||||||||||||||||||
250 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
251 | - | |||||||||||||||||||||||||||||||
252 | len = (size_t)data_len; | - | ||||||||||||||||||||||||||||||
253 | offset = 0; | - | ||||||||||||||||||||||||||||||
254 | - | |||||||||||||||||||||||||||||||
255 | if (ftruncate(sfd, len) == -1) {
| 0 | ||||||||||||||||||||||||||||||
256 | tls_set_error(ctx, "failed to truncate session file"); | - | ||||||||||||||||||||||||||||||
257 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
258 | } | - | ||||||||||||||||||||||||||||||
259 | while (len > 0) {
| 0 | ||||||||||||||||||||||||||||||
260 | if ((n = pwrite(sfd, data + offset, len, offset)) == -1) {
| 0 | ||||||||||||||||||||||||||||||
261 | tls_set_error(ctx, "failed to write session file"); | - | ||||||||||||||||||||||||||||||
262 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
263 | } | - | ||||||||||||||||||||||||||||||
264 | offset += n; | - | ||||||||||||||||||||||||||||||
265 | len -= n; | - | ||||||||||||||||||||||||||||||
266 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
267 | - | |||||||||||||||||||||||||||||||
268 | done: code before this statement never executed: done: | 0 | ||||||||||||||||||||||||||||||
269 | rv = 0; | - | ||||||||||||||||||||||||||||||
270 | - | |||||||||||||||||||||||||||||||
271 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||||||||||||||
272 | SSL_SESSION_free(ss); | - | ||||||||||||||||||||||||||||||
273 | BIO_free_all(bio); | - | ||||||||||||||||||||||||||||||
274 | - | |||||||||||||||||||||||||||||||
275 | return (rv); never executed: return (rv); | 0 | ||||||||||||||||||||||||||||||
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) {
| 0-4 | ||||||||||||||||||||||||||||||
285 | tls_set_errorx(ctx, "not a client context"); | - | ||||||||||||||||||||||||||||||
286 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
287 | } | - | ||||||||||||||||||||||||||||||
288 | - | |||||||||||||||||||||||||||||||
289 | if (servername != NULL) {
| 0-4 | ||||||||||||||||||||||||||||||
290 | if ((ctx->servername = strdup(servername)) == NULL) { never executed: __retval = (char *) memcpy (__retval, servername , __len);
| 0-4 | ||||||||||||||||||||||||||||||
291 | tls_set_errorx(ctx, "out of memory"); | - | ||||||||||||||||||||||||||||||
292 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
293 | } | - | ||||||||||||||||||||||||||||||
294 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||||||||||||||||||||
295 | - | |||||||||||||||||||||||||||||||
296 | if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
| 0-4 | ||||||||||||||||||||||||||||||
297 | tls_set_errorx(ctx, "ssl context failure"); | - | ||||||||||||||||||||||||||||||
298 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
299 | } | - | ||||||||||||||||||||||||||||||
300 | - | |||||||||||||||||||||||||||||||
301 | if (tls_configure_ssl(ctx, ctx->ssl_ctx) != 0)
| 0-4 | ||||||||||||||||||||||||||||||
302 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
303 | - | |||||||||||||||||||||||||||||||
304 | if (tls_configure_ssl_keypair(ctx, ctx->ssl_ctx,
| 0-4 | ||||||||||||||||||||||||||||||
305 | ctx->config->keypair, 0) != 0)
| 0-4 | ||||||||||||||||||||||||||||||
306 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
307 | - | |||||||||||||||||||||||||||||||
308 | if (ctx->config->verify_name) {
| 0-4 | ||||||||||||||||||||||||||||||
309 | if (servername == NULL) {
| 0 | ||||||||||||||||||||||||||||||
310 | tls_set_errorx(ctx, "server name not specified"); | - | ||||||||||||||||||||||||||||||
311 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
312 | } | - | ||||||||||||||||||||||||||||||
313 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
314 | - | |||||||||||||||||||||||||||||||
315 | if (tls_configure_ssl_verify(ctx, ctx->ssl_ctx, SSL_VERIFY_PEER) == -1)
| 0-4 | ||||||||||||||||||||||||||||||
316 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
317 | - | |||||||||||||||||||||||||||||||
318 | if (ctx->config->ecdhecurves != NULL) {
| 0-4 | ||||||||||||||||||||||||||||||
319 | if (SSL_CTX_set1_groups(ctx->ssl_ctx, ctx->config->ecdhecurves,
| 0-4 | ||||||||||||||||||||||||||||||
320 | ctx->config->ecdhecurves_len) != 1) {
| 0-4 | ||||||||||||||||||||||||||||||
321 | tls_set_errorx(ctx, "failed to set ecdhe curves"); | - | ||||||||||||||||||||||||||||||
322 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
323 | } | - | ||||||||||||||||||||||||||||||
324 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||||||||||||||||||||
325 | - | |||||||||||||||||||||||||||||||
326 | if (SSL_CTX_set_tlsext_status_cb(ctx->ssl_ctx, tls_ocsp_verify_cb) != 1) {
| 0-4 | ||||||||||||||||||||||||||||||
327 | tls_set_errorx(ctx, "ssl OCSP verification setup failure"); | - | ||||||||||||||||||||||||||||||
328 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
329 | } | - | ||||||||||||||||||||||||||||||
330 | - | |||||||||||||||||||||||||||||||
331 | if ((ctx->ssl_conn = SSL_new(ctx->ssl_ctx)) == NULL) {
| 0-4 | ||||||||||||||||||||||||||||||
332 | tls_set_errorx(ctx, "ssl connection failure"); | - | ||||||||||||||||||||||||||||||
333 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
334 | } | - | ||||||||||||||||||||||||||||||
335 | - | |||||||||||||||||||||||||||||||
336 | if (SSL_set_app_data(ctx->ssl_conn, ctx) != 1) {
| 0-4 | ||||||||||||||||||||||||||||||
337 | tls_set_errorx(ctx, "ssl application data failure"); | - | ||||||||||||||||||||||||||||||
338 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
339 | } | - | ||||||||||||||||||||||||||||||
340 | - | |||||||||||||||||||||||||||||||
341 | if (ctx->config->session_fd != -1) {
| 0-4 | ||||||||||||||||||||||||||||||
342 | SSL_clear_options(ctx->ssl_conn, SSL_OP_NO_TICKET); | - | ||||||||||||||||||||||||||||||
343 | if (tls_client_read_session(ctx) == -1)
| 0 | ||||||||||||||||||||||||||||||
344 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
345 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
346 | - | |||||||||||||||||||||||||||||||
347 | if (SSL_set_tlsext_status_type(ctx->ssl_conn, TLSEXT_STATUSTYPE_ocsp) != 1) {
| 0-4 | ||||||||||||||||||||||||||||||
348 | tls_set_errorx(ctx, "ssl OCSP extension setup failure"); | - | ||||||||||||||||||||||||||||||
349 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
350 | } | - | ||||||||||||||||||||||||||||||
351 | - | |||||||||||||||||||||||||||||||
352 | /* | - | ||||||||||||||||||||||||||||||
353 | * RFC4366 (SNI): Literal IPv4 and IPv6 addresses are not | - | ||||||||||||||||||||||||||||||
354 | * permitted in "HostName". | - | ||||||||||||||||||||||||||||||
355 | */ | - | ||||||||||||||||||||||||||||||
356 | if (servername != NULL &&
| 0-4 | ||||||||||||||||||||||||||||||
357 | inet_pton(AF_INET, servername, &addrbuf) != 1 &&
| 0-4 | ||||||||||||||||||||||||||||||
358 | inet_pton(AF_INET6, servername, &addrbuf) != 1) {
| 0-4 | ||||||||||||||||||||||||||||||
359 | if (SSL_set_tlsext_host_name(ctx->ssl_conn, servername) == 0) {
| 0-4 | ||||||||||||||||||||||||||||||
360 | tls_set_errorx(ctx, "server name indication failure"); | - | ||||||||||||||||||||||||||||||
361 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
362 | } | - | ||||||||||||||||||||||||||||||
363 | } executed 4 times by 1 test: end of block Executed by:
| 4 | ||||||||||||||||||||||||||||||
364 | - | |||||||||||||||||||||||||||||||
365 | ctx->state |= TLS_CONNECTED; | - | ||||||||||||||||||||||||||||||
366 | rv = 0; | - | ||||||||||||||||||||||||||||||
367 | - | |||||||||||||||||||||||||||||||
368 | err: code before this statement executed 4 times by 1 test: err: Executed by:
| 4 | ||||||||||||||||||||||||||||||
369 | return (rv); executed 4 times by 1 test: return (rv); Executed by:
| 4 | ||||||||||||||||||||||||||||||
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); executed 1 time by 1 test: return tls_connect_fds(ctx, s, s, servername); Executed by:
| 1 | ||||||||||||||||||||||||||||||
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) {
| 0-2 | ||||||||||||||||||||||||||||||
385 | tls_set_errorx(ctx, "invalid file descriptors"); | - | ||||||||||||||||||||||||||||||
386 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
387 | } | - | ||||||||||||||||||||||||||||||
388 | - | |||||||||||||||||||||||||||||||
389 | if (tls_connect_common(ctx, servername) != 0)
| 0-2 | ||||||||||||||||||||||||||||||
390 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
391 | - | |||||||||||||||||||||||||||||||
392 | if (SSL_set_rfd(ctx->ssl_conn, fd_read) != 1 ||
| 0-2 | ||||||||||||||||||||||||||||||
393 | SSL_set_wfd(ctx->ssl_conn, fd_write) != 1) {
| 0-2 | ||||||||||||||||||||||||||||||
394 | tls_set_errorx(ctx, "ssl file descriptor failure"); | - | ||||||||||||||||||||||||||||||
395 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
396 | } | - | ||||||||||||||||||||||||||||||
397 | - | |||||||||||||||||||||||||||||||
398 | rv = 0; | - | ||||||||||||||||||||||||||||||
399 | err: code before this statement executed 2 times by 1 test: err: Executed by:
| 2 | ||||||||||||||||||||||||||||||
400 | return (rv); executed 2 times by 1 test: return (rv); Executed by:
| 2 | ||||||||||||||||||||||||||||||
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)
| 0-2 | ||||||||||||||||||||||||||||||
410 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
411 | - | |||||||||||||||||||||||||||||||
412 | if (tls_set_cbs(ctx, read_cb, write_cb, cb_arg) != 0)
| 0-2 | ||||||||||||||||||||||||||||||
413 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
414 | - | |||||||||||||||||||||||||||||||
415 | rv = 0; | - | ||||||||||||||||||||||||||||||
416 | - | |||||||||||||||||||||||||||||||
417 | err: code before this statement executed 2 times by 1 test: err: Executed by:
| 2 | ||||||||||||||||||||||||||||||
418 | return (rv); executed 2 times by 1 test: return (rv); Executed by:
| 2 | ||||||||||||||||||||||||||||||
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) {
| 0-17 | ||||||||||||||||||||||||||||||
429 | tls_set_errorx(ctx, "not a client context"); | - | ||||||||||||||||||||||||||||||
430 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
431 | } | - | ||||||||||||||||||||||||||||||
432 | - | |||||||||||||||||||||||||||||||
433 | if ((ctx->state & TLS_CONNECTED) == 0) {
| 1-16 | ||||||||||||||||||||||||||||||
434 | tls_set_errorx(ctx, "context not connected"); | - | ||||||||||||||||||||||||||||||
435 | goto err; executed 1 time by 1 test: goto err; Executed by:
| 1 | ||||||||||||||||||||||||||||||
436 | } | - | ||||||||||||||||||||||||||||||
437 | - | |||||||||||||||||||||||||||||||
438 | ctx->state |= TLS_SSL_NEEDS_SHUTDOWN; | - | ||||||||||||||||||||||||||||||
439 | - | |||||||||||||||||||||||||||||||
440 | ERR_clear_error(); | - | ||||||||||||||||||||||||||||||
441 | if ((ssl_ret = SSL_connect(ctx->ssl_conn)) != 1) {
| 4-12 | ||||||||||||||||||||||||||||||
442 | rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); | - | ||||||||||||||||||||||||||||||
443 | goto err; executed 12 times by 1 test: goto err; Executed by:
| 12 | ||||||||||||||||||||||||||||||
444 | } | - | ||||||||||||||||||||||||||||||
445 | - | |||||||||||||||||||||||||||||||
446 | if (ctx->config->verify_name) {
| 0-4 | ||||||||||||||||||||||||||||||
447 | cert = SSL_get_peer_certificate(ctx->ssl_conn); | - | ||||||||||||||||||||||||||||||
448 | if (cert == NULL) {
| 0 | ||||||||||||||||||||||||||||||
449 | tls_set_errorx(ctx, "no server certificate"); | - | ||||||||||||||||||||||||||||||
450 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
451 | } | - | ||||||||||||||||||||||||||||||
452 | if (tls_check_name(ctx, cert, ctx->servername, &match) == -1)
| 0 | ||||||||||||||||||||||||||||||
453 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
454 | if (!match) {
| 0 | ||||||||||||||||||||||||||||||
455 | tls_set_errorx(ctx, "name `%s' not present in" | - | ||||||||||||||||||||||||||||||
456 | " server certificate", ctx->servername); | - | ||||||||||||||||||||||||||||||
457 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
458 | } | - | ||||||||||||||||||||||||||||||
459 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
460 | - | |||||||||||||||||||||||||||||||
461 | ctx->state |= TLS_HANDSHAKE_COMPLETE; | - | ||||||||||||||||||||||||||||||
462 | - | |||||||||||||||||||||||||||||||
463 | if (ctx->config->session_fd != -1) {
| 0-4 | ||||||||||||||||||||||||||||||
464 | if (tls_client_write_session(ctx) == -1)
| 0 | ||||||||||||||||||||||||||||||
465 | goto err; never executed: goto err; | 0 | ||||||||||||||||||||||||||||||
466 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
467 | - | |||||||||||||||||||||||||||||||
468 | rv = 0; | - | ||||||||||||||||||||||||||||||
469 | - | |||||||||||||||||||||||||||||||
470 | err: code before this statement executed 4 times by 1 test: err: Executed by:
| 4 | ||||||||||||||||||||||||||||||
471 | X509_free(cert); | - | ||||||||||||||||||||||||||||||
472 | - | |||||||||||||||||||||||||||||||
473 | return (rv); executed 17 times by 1 test: return (rv); Executed by:
| 17 | ||||||||||||||||||||||||||||||
474 | } | - | ||||||||||||||||||||||||||||||
Source code | Switch to Preprocessed file |