diff options
author | jsing <> | 2014-10-31 13:46:17 +0000 |
---|---|---|
committer | jsing <> | 2014-10-31 13:46:17 +0000 |
commit | cd85e00508e178758948e7a759609d0f1e7764df (patch) | |
tree | 44ea21a19ccf529a3e38fb107d3a2d1330f58d8e /src/lib/libressl/ressl_verify.c | |
parent | e83bdb8edcd9388f13b71372b277fdcce386a9b0 (diff) | |
download | openbsd-cd85e00508e178758948e7a759609d0f1e7764df.tar.gz openbsd-cd85e00508e178758948e7a759609d0f1e7764df.tar.bz2 openbsd-cd85e00508e178758948e7a759609d0f1e7764df.zip |
Rename libressl to libtls to avoid confusion and to make it easier to
distinguish between LibreSSL (the project) and libressl (the library).
Discussed with many.
Diffstat (limited to 'src/lib/libressl/ressl_verify.c')
-rw-r--r-- | src/lib/libressl/ressl_verify.c | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/src/lib/libressl/ressl_verify.c b/src/lib/libressl/ressl_verify.c deleted file mode 100644 index 5e9f370e1c..0000000000 --- a/src/lib/libressl/ressl_verify.c +++ /dev/null | |||
@@ -1,225 +0,0 @@ | |||
1 | /* $OpenBSD: ressl_verify.c,v 1.5 2014/10/06 11:55:48 jca 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 "ressl_internal.h" | ||
28 | |||
29 | int ressl_match_hostname(const char *cert_hostname, const char *hostname); | ||
30 | int ressl_check_subject_altname(X509 *cert, const char *host); | ||
31 | int ressl_check_common_name(X509 *cert, const char *host); | ||
32 | |||
33 | int | ||
34 | ressl_match_hostname(const char *cert_hostname, const char *hostname) | ||
35 | { | ||
36 | const char *cert_domain, *domain, *next_dot; | ||
37 | |||
38 | if (strcasecmp(cert_hostname, hostname) == 0) | ||
39 | return 0; | ||
40 | |||
41 | /* Wildcard match? */ | ||
42 | if (cert_hostname[0] == '*') { | ||
43 | /* | ||
44 | * Valid wildcards: | ||
45 | * - "*.domain.tld" | ||
46 | * - "*.sub.domain.tld" | ||
47 | * - etc. | ||
48 | * Reject "*.tld". | ||
49 | * No attempt to prevent the use of eg. "*.co.uk". | ||
50 | */ | ||
51 | cert_domain = &cert_hostname[1]; | ||
52 | /* Disallow "*" */ | ||
53 | if (cert_domain[0] == '\0') | ||
54 | return -1; | ||
55 | /* Disallow "*foo" */ | ||
56 | if (cert_domain[0] != '.') | ||
57 | return -1; | ||
58 | /* Disallow "*.." */ | ||
59 | if (cert_domain[1] == '.') | ||
60 | return -1; | ||
61 | next_dot = strchr(&cert_domain[1], '.'); | ||
62 | /* Disallow "*.bar" */ | ||
63 | if (next_dot == NULL) | ||
64 | return -1; | ||
65 | /* Disallow "*.bar.." */ | ||
66 | if (next_dot[1] == '.') | ||
67 | return -1; | ||
68 | |||
69 | domain = strchr(hostname, '.'); | ||
70 | |||
71 | /* No wildcard match against a hostname with no domain part. */ | ||
72 | if (domain == NULL || strlen(domain) == 1) | ||
73 | return -1; | ||
74 | |||
75 | if (strcasecmp(cert_domain, domain) == 0) | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | return -1; | ||
80 | } | ||
81 | |||
82 | int | ||
83 | ressl_check_subject_altname(X509 *cert, const char *host) | ||
84 | { | ||
85 | STACK_OF(GENERAL_NAME) *altname_stack = NULL; | ||
86 | union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; | ||
87 | int addrlen, type; | ||
88 | int count, i; | ||
89 | int rv = -1; | ||
90 | |||
91 | altname_stack = X509_get_ext_d2i(cert, NID_subject_alt_name, | ||
92 | NULL, NULL); | ||
93 | if (altname_stack == NULL) | ||
94 | return -1; | ||
95 | |||
96 | if (inet_pton(AF_INET, host, &addrbuf) == 1) { | ||
97 | type = GEN_IPADD; | ||
98 | addrlen = 4; | ||
99 | } else if (inet_pton(AF_INET6, host, &addrbuf) == 1) { | ||
100 | type = GEN_IPADD; | ||
101 | addrlen = 16; | ||
102 | } else { | ||
103 | type = GEN_DNS; | ||
104 | addrlen = 0; | ||
105 | } | ||
106 | |||
107 | count = sk_GENERAL_NAME_num(altname_stack); | ||
108 | for (i = 0; i < count; i++) { | ||
109 | GENERAL_NAME *altname; | ||
110 | |||
111 | altname = sk_GENERAL_NAME_value(altname_stack, i); | ||
112 | |||
113 | if (altname->type != type) | ||
114 | continue; | ||
115 | |||
116 | if (type == GEN_DNS) { | ||
117 | unsigned char *data; | ||
118 | int format; | ||
119 | |||
120 | format = ASN1_STRING_type(altname->d.dNSName); | ||
121 | if (format == V_ASN1_IA5STRING) { | ||
122 | data = ASN1_STRING_data(altname->d.dNSName); | ||
123 | |||
124 | if (ASN1_STRING_length(altname->d.dNSName) != | ||
125 | (int)strlen(data)) { | ||
126 | fprintf(stdout, "%s: NUL byte in " | ||
127 | "subjectAltName, probably a " | ||
128 | "malicious certificate.\n", | ||
129 | getprogname()); | ||
130 | rv = -2; | ||
131 | break; | ||
132 | } | ||
133 | |||
134 | if (ressl_match_hostname(data, host) == 0) { | ||
135 | rv = 0; | ||
136 | break; | ||
137 | } | ||
138 | } else | ||
139 | fprintf(stdout, "%s: unhandled subjectAltName " | ||
140 | "dNSName encoding (%d)\n", getprogname(), | ||
141 | format); | ||
142 | |||
143 | } else if (type == GEN_IPADD) { | ||
144 | unsigned char *data; | ||
145 | int datalen; | ||
146 | |||
147 | datalen = ASN1_STRING_length(altname->d.iPAddress); | ||
148 | data = ASN1_STRING_data(altname->d.iPAddress); | ||
149 | |||
150 | if (datalen == addrlen && | ||
151 | memcmp(data, &addrbuf, addrlen) == 0) { | ||
152 | rv = 0; | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | |||
158 | sk_GENERAL_NAME_free(altname_stack); | ||
159 | return rv; | ||
160 | } | ||
161 | |||
162 | int | ||
163 | ressl_check_common_name(X509 *cert, const char *host) | ||
164 | { | ||
165 | X509_NAME *name; | ||
166 | char *common_name = NULL; | ||
167 | int common_name_len; | ||
168 | int rv = -1; | ||
169 | union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; | ||
170 | |||
171 | name = X509_get_subject_name(cert); | ||
172 | if (name == NULL) | ||
173 | goto out; | ||
174 | |||
175 | common_name_len = X509_NAME_get_text_by_NID(name, NID_commonName, | ||
176 | NULL, 0); | ||
177 | if (common_name_len < 0) | ||
178 | goto out; | ||
179 | |||
180 | common_name = calloc(common_name_len + 1, 1); | ||
181 | if (common_name == NULL) | ||
182 | goto out; | ||
183 | |||
184 | X509_NAME_get_text_by_NID(name, NID_commonName, common_name, | ||
185 | common_name_len + 1); | ||
186 | |||
187 | /* NUL bytes in CN? */ | ||
188 | if (common_name_len != (int)strlen(common_name)) { | ||
189 | fprintf(stdout, "%s: NUL byte in Common Name field, " | ||
190 | "probably a malicious certificate.\n", getprogname()); | ||
191 | rv = -2; | ||
192 | goto out; | ||
193 | } | ||
194 | |||
195 | if (inet_pton(AF_INET, host, &addrbuf) == 1 || | ||
196 | inet_pton(AF_INET6, host, &addrbuf) == 1) { | ||
197 | /* | ||
198 | * We don't want to attempt wildcard matching against IP | ||
199 | * addresses, so perform a simple comparison here. | ||
200 | */ | ||
201 | if (strcmp(common_name, host) == 0) | ||
202 | rv = 0; | ||
203 | else | ||
204 | rv = -1; | ||
205 | goto out; | ||
206 | } | ||
207 | |||
208 | if (ressl_match_hostname(common_name, host) == 0) | ||
209 | rv = 0; | ||
210 | out: | ||
211 | free(common_name); | ||
212 | return rv; | ||
213 | } | ||
214 | |||
215 | int | ||
216 | ressl_check_hostname(X509 *cert, const char *host) | ||
217 | { | ||
218 | int rv; | ||
219 | |||
220 | rv = ressl_check_subject_altname(cert, host); | ||
221 | if (rv == 0 || rv == -2) | ||
222 | return rv; | ||
223 | |||
224 | return ressl_check_common_name(cert, host); | ||
225 | } | ||