summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libtls/tls_verify.c')
-rw-r--r--src/lib/libtls/tls_verify.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/src/lib/libtls/tls_verify.c b/src/lib/libtls/tls_verify.c
index 4341802b5a..c1a5387829 100644
--- a/src/lib/libtls/tls_verify.c
+++ b/src/lib/libtls/tls_verify.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_verify.c,v 1.6 2014/12/17 17:51:33 doug Exp $ */ 1/* $OpenBSD: tls_verify.c,v 1.7 2015/02/11 06:46:33 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> 3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
4 * 4 *
@@ -26,20 +26,20 @@
26 26
27#include "tls_internal.h" 27#include "tls_internal.h"
28 28
29int tls_match_hostname(const char *cert_hostname, const char *hostname); 29int tls_match_name(const char *cert_name, const char *name);
30int tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *host); 30int tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name);
31int tls_check_common_name(struct tls *ctx, X509 *cert, const char *host); 31int tls_check_common_name(struct tls *ctx, X509 *cert, const char *name);
32 32
33int 33int
34tls_match_hostname(const char *cert_hostname, const char *hostname) 34tls_match_name(const char *cert_name, const char *name)
35{ 35{
36 const char *cert_domain, *domain, *next_dot; 36 const char *cert_domain, *domain, *next_dot;
37 37
38 if (strcasecmp(cert_hostname, hostname) == 0) 38 if (strcasecmp(cert_name, name) == 0)
39 return 0; 39 return 0;
40 40
41 /* Wildcard match? */ 41 /* Wildcard match? */
42 if (cert_hostname[0] == '*') { 42 if (cert_name[0] == '*') {
43 /* 43 /*
44 * Valid wildcards: 44 * Valid wildcards:
45 * - "*.domain.tld" 45 * - "*.domain.tld"
@@ -48,7 +48,7 @@ tls_match_hostname(const char *cert_hostname, const char *hostname)
48 * Reject "*.tld". 48 * Reject "*.tld".
49 * No attempt to prevent the use of eg. "*.co.uk". 49 * No attempt to prevent the use of eg. "*.co.uk".
50 */ 50 */
51 cert_domain = &cert_hostname[1]; 51 cert_domain = &cert_name[1];
52 /* Disallow "*" */ 52 /* Disallow "*" */
53 if (cert_domain[0] == '\0') 53 if (cert_domain[0] == '\0')
54 return -1; 54 return -1;
@@ -66,9 +66,9 @@ tls_match_hostname(const char *cert_hostname, const char *hostname)
66 if (next_dot[1] == '.') 66 if (next_dot[1] == '.')
67 return -1; 67 return -1;
68 68
69 domain = strchr(hostname, '.'); 69 domain = strchr(name, '.');
70 70
71 /* No wildcard match against a hostname with no domain part. */ 71 /* No wildcard match against a name with no domain part. */
72 if (domain == NULL || strlen(domain) == 1) 72 if (domain == NULL || strlen(domain) == 1)
73 return -1; 73 return -1;
74 74
@@ -80,7 +80,7 @@ tls_match_hostname(const char *cert_hostname, const char *hostname)
80} 80}
81 81
82int 82int
83tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *host) 83tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name)
84{ 84{
85 STACK_OF(GENERAL_NAME) *altname_stack = NULL; 85 STACK_OF(GENERAL_NAME) *altname_stack = NULL;
86 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; 86 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
@@ -93,10 +93,10 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *host)
93 if (altname_stack == NULL) 93 if (altname_stack == NULL)
94 return -1; 94 return -1;
95 95
96 if (inet_pton(AF_INET, host, &addrbuf) == 1) { 96 if (inet_pton(AF_INET, name, &addrbuf) == 1) {
97 type = GEN_IPADD; 97 type = GEN_IPADD;
98 addrlen = 4; 98 addrlen = 4;
99 } else if (inet_pton(AF_INET6, host, &addrbuf) == 1) { 99 } else if (inet_pton(AF_INET6, name, &addrbuf) == 1) {
100 type = GEN_IPADD; 100 type = GEN_IPADD;
101 addrlen = 16; 101 addrlen = 16;
102 } else { 102 } else {
@@ -124,15 +124,15 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *host)
124 124
125 if (len < 0 || len != strlen(data)) { 125 if (len < 0 || len != strlen(data)) {
126 tls_set_error(ctx, 126 tls_set_error(ctx,
127 "error verifying host '%s': " 127 "error verifying name '%s': "
128 "NUL byte in subjectAltName, " 128 "NUL byte in subjectAltName, "
129 "probably a malicious certificate", 129 "probably a malicious certificate",
130 host); 130 name);
131 rv = -2; 131 rv = -2;
132 break; 132 break;
133 } 133 }
134 134
135 if (tls_match_hostname(data, host) == 0) { 135 if (tls_match_name(data, name) == 0) {
136 rv = 0; 136 rv = 0;
137 break; 137 break;
138 } 138 }
@@ -172,20 +172,20 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *host)
172} 172}
173 173
174int 174int
175tls_check_common_name(struct tls *ctx, X509 *cert, const char *host) 175tls_check_common_name(struct tls *ctx, X509 *cert, const char *name)
176{ 176{
177 X509_NAME *name; 177 X509_NAME *subject_name;
178 char *common_name = NULL; 178 char *common_name = NULL;
179 int common_name_len; 179 int common_name_len;
180 int rv = -1; 180 int rv = -1;
181 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; 181 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
182 182
183 name = X509_get_subject_name(cert); 183 subject_name = X509_get_subject_name(cert);
184 if (name == NULL) 184 if (subject_name == NULL)
185 goto out; 185 goto out;
186 186
187 common_name_len = X509_NAME_get_text_by_NID(name, NID_commonName, 187 common_name_len = X509_NAME_get_text_by_NID(subject_name,
188 NULL, 0); 188 NID_commonName, NULL, 0);
189 if (common_name_len < 0) 189 if (common_name_len < 0)
190 goto out; 190 goto out;
191 191
@@ -193,32 +193,32 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *host)
193 if (common_name == NULL) 193 if (common_name == NULL)
194 goto out; 194 goto out;
195 195
196 X509_NAME_get_text_by_NID(name, NID_commonName, common_name, 196 X509_NAME_get_text_by_NID(subject_name, NID_commonName, common_name,
197 common_name_len + 1); 197 common_name_len + 1);
198 198
199 /* NUL bytes in CN? */ 199 /* NUL bytes in CN? */
200 if (common_name_len != strlen(common_name)) { 200 if (common_name_len != strlen(common_name)) {
201 tls_set_error(ctx, "error verifying host '%s': " 201 tls_set_error(ctx, "error verifying name '%s': "
202 "NUL byte in Common Name field, " 202 "NUL byte in Common Name field, "
203 "probably a malicious certificate.", host); 203 "probably a malicious certificate", name);
204 rv = -2; 204 rv = -2;
205 goto out; 205 goto out;
206 } 206 }
207 207
208 if (inet_pton(AF_INET, host, &addrbuf) == 1 || 208 if (inet_pton(AF_INET, name, &addrbuf) == 1 ||
209 inet_pton(AF_INET6, host, &addrbuf) == 1) { 209 inet_pton(AF_INET6, name, &addrbuf) == 1) {
210 /* 210 /*
211 * We don't want to attempt wildcard matching against IP 211 * We don't want to attempt wildcard matching against IP
212 * addresses, so perform a simple comparison here. 212 * addresses, so perform a simple comparison here.
213 */ 213 */
214 if (strcmp(common_name, host) == 0) 214 if (strcmp(common_name, name) == 0)
215 rv = 0; 215 rv = 0;
216 else 216 else
217 rv = -1; 217 rv = -1;
218 goto out; 218 goto out;
219 } 219 }
220 220
221 if (tls_match_hostname(common_name, host) == 0) 221 if (tls_match_name(common_name, name) == 0)
222 rv = 0; 222 rv = 0;
223out: 223out:
224 free(common_name); 224 free(common_name);
@@ -226,13 +226,13 @@ out:
226} 226}
227 227
228int 228int
229tls_check_hostname(struct tls *ctx, X509 *cert, const char *host) 229tls_check_servername(struct tls *ctx, X509 *cert, const char *servername)
230{ 230{
231 int rv; 231 int rv;
232 232
233 rv = tls_check_subject_altname(ctx, cert, host); 233 rv = tls_check_subject_altname(ctx, cert, servername);
234 if (rv == 0 || rv == -2) 234 if (rv == 0 || rv == -2)
235 return rv; 235 return rv;
236 236
237 return tls_check_common_name(ctx, cert, host); 237 return tls_check_common_name(ctx, cert, servername);
238} 238}