OpenCoverage

tls_verify.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/libressl/src/tls/tls_verify.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: tls_verify.c,v 1.20 2018/02/05 00:52:24 jsing Exp $ */-
2/*-
3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@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/socket.h>-
19-
20#include <arpa/inet.h>-
21#include <netinet/in.h>-
22-
23#include <string.h>-
24-
25#include <openssl/x509v3.h>-
26-
27#include <tls.h>-
28#include "tls_internal.h"-
29-
30static int-
31tls_match_name(const char *cert_name, const char *name)-
32{-
33 const char *cert_domain, *domain, *next_dot;-
34-
35 if (strcasecmp(cert_name, name) == 0)
strcasecmp(cer...me, name) == 0Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 20 times by 1 test
Evaluated by:
  • verifytest
5-20
36 return 0;
executed 5 times by 1 test: return 0;
Executed by:
  • verifytest
5
37-
38 /* Wildcard match? */-
39 if (cert_name[0] == '*') {
cert_name[0] == '*'Description
TRUEevaluated 7 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 13 times by 1 test
Evaluated by:
  • verifytest
7-13
40 /*-
41 * Valid wildcards:-
42 * - "*.domain.tld"-
43 * - "*.sub.domain.tld"-
44 * - etc.-
45 * Reject "*.tld".-
46 * No attempt to prevent the use of eg. "*.co.uk".-
47 */-
48 cert_domain = &cert_name[1];-
49 /* Disallow "*" */-
50 if (cert_domain[0] == '\0')
cert_domain[0] == '\0'Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 6 times by 1 test
Evaluated by:
  • verifytest
1-6
51 return -1;
executed 1 time by 1 test: return -1;
Executed by:
  • verifytest
1
52 /* Disallow "*foo" */-
53 if (cert_domain[0] != '.')
cert_domain[0] != '.'Description
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • verifytest
0-6
54 return -1;
never executed: return -1;
0
55 /* Disallow "*.." */-
56 if (cert_domain[1] == '.')
cert_domain[1] == '.'Description
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • verifytest
0-6
57 return -1;
never executed: return -1;
0
58 next_dot = strchr(&cert_domain[1], '.');
__builtin_constant_p ( '.' )Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
!__builtin_con...rt_domain[1] )Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
( '.' ) == '\0'Description
TRUEnever evaluated
FALSEevaluated 6 times by 1 test
Evaluated by:
  • verifytest
0-6
59 /* Disallow "*.bar" */-
60 if (next_dot == NULL)
next_dot == ((void *)0)Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 3 times by 1 test
Evaluated by:
  • verifytest
3
61 return -1;
executed 3 times by 1 test: return -1;
Executed by:
  • verifytest
3
62 /* Disallow "*.bar.." */-
63 if (next_dot[1] == '.')
next_dot[1] == '.'Description
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • verifytest
0-3
64 return -1;
never executed: return -1;
0
65-
66 domain = strchr(name, '.');
__builtin_constant_p ( '.' )Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
!__builtin_constant_p ( name )Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
( '.' ) == '\0'Description
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • verifytest
0-3
67-
68 /* No wildcard match against a name with no host part. */-
69 if (name[0] == '.')
name[0] == '.'Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
1-2
70 return -1;
executed 1 time by 1 test: return -1;
Executed by:
  • verifytest
1
71 /* No wildcard match against a name with no domain part. */-
72 if (domain == NULL || strlen(domain) == 1)
domain == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
strlen(domain) == 1Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
0-2
73 return -1;
never executed: return -1;
0
74-
75 if (strcasecmp(cert_domain, domain) == 0)
strcasecmp(cer..., domain) == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
0-2
76 return 0;
executed 2 times by 1 test: return 0;
Executed by:
  • verifytest
2
77 }
never executed: end of block
0
78-
79 return -1;
executed 13 times by 1 test: return -1;
Executed by:
  • verifytest
13
80}-
81-
82/*-
83 * See RFC 5280 section 4.2.1.6 for SubjectAltName details.-
84 * alt_match is set to 1 if a matching alternate name is found.-
85 * alt_exists is set to 1 if any known alternate name exists in the certificate.-
86 */-
87static int-
88tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name,-
89 int *alt_match, int *alt_exists)-
90{-
91 STACK_OF(GENERAL_NAME) *altname_stack = NULL;-
92 union tls_addr addrbuf;-
93 int addrlen, type;-
94 int count, i;-
95 int rv = 0;-
96-
97 *alt_match = 0;-
98 *alt_exists = 0;-
99-
100 altname_stack = X509_get_ext_d2i(cert, NID_subject_alt_name,-
101 NULL, NULL);-
102 if (altname_stack == NULL)
altname_stack == ((void *)0)Description
TRUEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 13 times by 1 test
Evaluated by:
  • verifytest
13-15
103 return 0;
executed 15 times by 1 test: return 0;
Executed by:
  • verifytest
15
104-
105 if (inet_pton(AF_INET, name, &addrbuf) == 1) {
inet_pton( 2 ,...&addrbuf) == 1Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 11 times by 1 test
Evaluated by:
  • verifytest
2-11
106 type = GEN_IPADD;-
107 addrlen = 4;-
108 } else if (inet_pton(AF_INET6, name, &addrbuf) == 1) {
executed 2 times by 1 test: end of block
Executed by:
  • verifytest
inet_pton( 10 ...&addrbuf) == 1Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 10 times by 1 test
Evaluated by:
  • verifytest
1-10
109 type = GEN_IPADD;-
110 addrlen = 16;-
111 } else {
executed 1 time by 1 test: end of block
Executed by:
  • verifytest
1
112 type = GEN_DNS;-
113 addrlen = 0;-
114 }
executed 10 times by 1 test: end of block
Executed by:
  • verifytest
10
115-
116 count = sk_GENERAL_NAME_num(altname_stack);-
117 for (i = 0; i < count; i++) {
i < countDescription
TRUEevaluated 22 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 4 times by 1 test
Evaluated by:
  • verifytest
4-22
118 GENERAL_NAME *altname;-
119-
120 altname = sk_GENERAL_NAME_value(altname_stack, i);-
121-
122 if (altname->type == GEN_DNS || altname->type == GEN_IPADD)
altname->type == 2Description
TRUEevaluated 20 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
altname->type == 7Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
0-20
123 *alt_exists = 1;
executed 22 times by 1 test: *alt_exists = 1;
Executed by:
  • verifytest
22
124-
125 if (altname->type != type)
altname->type != typeDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 18 times by 1 test
Evaluated by:
  • verifytest
4-18
126 continue;
executed 4 times by 1 test: continue;
Executed by:
  • verifytest
4
127-
128 if (type == GEN_DNS) {
type == 2Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
2-16
129 unsigned char *data;-
130 int format, len;-
131-
132 format = ASN1_STRING_type(altname->d.dNSName);-
133 if (format == V_ASN1_IA5STRING) {
format == 22Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
0-16
134 data = ASN1_STRING_data(altname->d.dNSName);-
135 len = ASN1_STRING_length(altname->d.dNSName);-
136-
137 if (len < 0 || (size_t)len != strlen(data)) {
len < 0Description
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • verifytest
(size_t)len != strlen(data)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
0-16
138 tls_set_errorx(ctx,-
139 "error verifying name '%s': "-
140 "NUL byte in subjectAltName, "-
141 "probably a malicious certificate",-
142 name);-
143 rv = -1;-
144 break;
executed 1 time by 1 test: break;
Executed by:
  • verifytest
1
145 }-
146-
147 /*-
148 * Per RFC 5280 section 4.2.1.6:-
149 * " " is a legal domain name, but that-
150 * dNSName must be rejected.-
151 */-
152 if (strcmp(data, " ") == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( data ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( " " ))[3] - __s2[3]);
never executed: end of block
executed 1 time by 1 test: end of block
Executed by:
  • verifytest
__extension__ ... )))); }) == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 14 times by 1 test
Evaluated by:
  • verifytest
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
__result == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 14 times by 1 test
Evaluated by:
  • verifytest
__s2_len > 1Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-15
153 tls_set_errorx(ctx,-
154 "error verifying name '%s': "-
155 "a dNSName of \" \" must not be "-
156 "used", name);-
157 rv = -1;-
158 break;
executed 1 time by 1 test: break;
Executed by:
  • verifytest
1
159 }-
160-
161 if (tls_match_name(data, name) == 0) {
tls_match_name...ta, name) == 0Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 9 times by 1 test
Evaluated by:
  • verifytest
5-9
162 *alt_match = 1;-
163 break;
executed 5 times by 1 test: break;
Executed by:
  • verifytest
5
164 }-
165 } else {
executed 9 times by 1 test: end of block
Executed by:
  • verifytest
9
166#ifdef DEBUG-
167 fprintf(stdout, "%s: unhandled subjectAltName "-
168 "dNSName encoding (%d)\n", getprogname(),-
169 format);-
170#endif-
171 }
never executed: end of block
0
172-
173 } else if (type == GEN_IPADD) {
type == 7Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
0-2
174 unsigned char *data;-
175 int datalen;-
176-
177 datalen = ASN1_STRING_length(altname->d.iPAddress);-
178 data = ASN1_STRING_data(altname->d.iPAddress);-
179-
180 if (datalen < 0) {
datalen < 0Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
0-2
181 tls_set_errorx(ctx,-
182 "Unexpected negative length for an "-
183 "IP address: %d", datalen);-
184 rv = -1;-
185 break;
never executed: break;
0
186 }-
187-
188 /*-
189 * Per RFC 5280 section 4.2.1.6:-
190 * IPv4 must use 4 octets and IPv6 must use 16 octets.-
191 */-
192 if (datalen == addrlen &&
datalen == addrlenDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
0-2
193 memcmp(data, &addrbuf, addrlen) == 0) {
memcmp(data, &... addrlen) == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEnever evaluated
0-2
194 *alt_match = 1;-
195 break;
executed 2 times by 1 test: break;
Executed by:
  • verifytest
2
196 }-
197 }
never executed: end of block
0
198 }
executed 9 times by 1 test: end of block
Executed by:
  • verifytest
9
199-
200 sk_GENERAL_NAME_pop_free(altname_stack, GENERAL_NAME_free);-
201 return rv;
executed 13 times by 1 test: return rv;
Executed by:
  • verifytest
13
202}-
203-
204static int-
205tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,-
206 int *cn_match)-
207{-
208 X509_NAME *subject_name;-
209 char *common_name = NULL;-
210 union tls_addr addrbuf;-
211 int common_name_len;-
212 int rv = 0;-
213-
214 *cn_match = 0;-
215-
216 subject_name = X509_get_subject_name(cert);-
217 if (subject_name == NULL)
subject_name == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
0-15
218 goto done;
never executed: goto done;
0
219-
220 common_name_len = X509_NAME_get_text_by_NID(subject_name,-
221 NID_commonName, NULL, 0);-
222 if (common_name_len < 0)
common_name_len < 0Description
TRUEnever evaluated
FALSEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
0-15
223 goto done;
never executed: goto done;
0
224-
225 common_name = calloc(common_name_len + 1, 1);-
226 if (common_name == NULL)
common_name == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
0-15
227 goto done;
never executed: goto done;
0
228-
229 X509_NAME_get_text_by_NID(subject_name, NID_commonName, common_name,-
230 common_name_len + 1);-
231-
232 /* NUL bytes in CN? */-
233 if (common_name_len < 0 ||
common_name_len < 0Description
TRUEnever evaluated
FALSEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
0-15
234 (size_t)common_name_len != strlen(common_name)) {
(size_t)common...n(common_name)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 14 times by 1 test
Evaluated by:
  • verifytest
1-14
235 tls_set_errorx(ctx, "error verifying name '%s': "-
236 "NUL byte in Common Name field, "-
237 "probably a malicious certificate", name);-
238 rv = -1;-
239 goto done;
executed 1 time by 1 test: goto done;
Executed by:
  • verifytest
1
240 }-
241-
242 /*-
243 * We don't want to attempt wildcard matching against IP addresses,-
244 * so perform a simple comparison here.-
245 */-
246 if (inet_pton(AF_INET, name, &addrbuf) == 1 ||
inet_pton( 2 ,...&addrbuf) == 1Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 12 times by 1 test
Evaluated by:
  • verifytest
2-12
247 inet_pton(AF_INET6, name, &addrbuf) == 1) {
inet_pton( 10 ...&addrbuf) == 1Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 11 times by 1 test
Evaluated by:
  • verifytest
1-11
248 if (strcmp(common_name, name) == 0)
never executed: __result = (((const unsigned char *) (const char *) ( common_name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 1 time by 1 test
Evaluated by:
  • verifytest
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-2
249 *cn_match = 1;
executed 2 times by 1 test: *cn_match = 1;
Executed by:
  • verifytest
2
250 goto done;
executed 3 times by 1 test: goto done;
Executed by:
  • verifytest
3
251 }-
252-
253 if (tls_match_name(common_name, name) == 0)
tls_match_name...me, name) == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 9 times by 1 test
Evaluated by:
  • verifytest
2-9
254 *cn_match = 1;
executed 2 times by 1 test: *cn_match = 1;
Executed by:
  • verifytest
2
255-
256 done:
code before this statement executed 11 times by 1 test: done:
Executed by:
  • verifytest
11
257 free(common_name);-
258 return rv;
executed 15 times by 1 test: return rv;
Executed by:
  • verifytest
15
259}-
260-
261int-
262tls_check_name(struct tls *ctx, X509 *cert, const char *name, int *match)-
263{-
264 int alt_exists;-
265-
266 *match = 0;-
267-
268 if (tls_check_subject_altname(ctx, cert, name, match,
tls_check_subj..._exists) == -1Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 26 times by 1 test
Evaluated by:
  • verifytest
2-26
269 &alt_exists) == -1)
tls_check_subj..._exists) == -1Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 26 times by 1 test
Evaluated by:
  • verifytest
2-26
270 return -1;
executed 2 times by 1 test: return -1;
Executed by:
  • verifytest
2
271-
272 /*-
273 * As per RFC 6125 section 6.4.4, if any known alternate name existed-
274 * in the certificate, we do not attempt to match on the CN.-
275 */-
276 if (*match || alt_exists)
*matchDescription
TRUEevaluated 7 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 19 times by 1 test
Evaluated by:
  • verifytest
alt_existsDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • verifytest
FALSEevaluated 15 times by 1 test
Evaluated by:
  • verifytest
4-19
277 return 0;
executed 11 times by 1 test: return 0;
Executed by:
  • verifytest
11
278-
279 return tls_check_common_name(ctx, cert, name, match);
executed 15 times by 1 test: return tls_check_common_name(ctx, cert, name, match);
Executed by:
  • verifytest
15
280}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2