summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libtls/tls.h3
-rw-r--r--src/lib/libtls/tls_conninfo.c14
-rw-r--r--src/lib/libtls/tls_internal.h5
-rw-r--r--src/lib/libtls/tls_peer.c10
-rw-r--r--src/lib/libtls/tls_verify.c97
5 files changed, 105 insertions, 24 deletions
diff --git a/src/lib/libtls/tls.h b/src/lib/libtls/tls.h
index 6b36886dc3..5a3a6254ab 100644
--- a/src/lib/libtls/tls.h
+++ b/src/lib/libtls/tls.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls.h,v 1.67 2024/08/02 15:00:01 tb Exp $ */ 1/* $OpenBSD: tls.h,v 1.68 2024/12/10 08:40:30 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -200,6 +200,7 @@ int tls_close(struct tls *_ctx);
200int tls_peer_cert_provided(struct tls *_ctx); 200int tls_peer_cert_provided(struct tls *_ctx);
201int tls_peer_cert_contains_name(struct tls *_ctx, const char *_name); 201int tls_peer_cert_contains_name(struct tls *_ctx, const char *_name);
202 202
203const char *tls_peer_cert_common_name(struct tls *_ctx);
203const char *tls_peer_cert_hash(struct tls *_ctx); 204const char *tls_peer_cert_hash(struct tls *_ctx);
204const char *tls_peer_cert_issuer(struct tls *_ctx); 205const char *tls_peer_cert_issuer(struct tls *_ctx);
205const char *tls_peer_cert_subject(struct tls *_ctx); 206const char *tls_peer_cert_subject(struct tls *_ctx);
diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/tls_conninfo.c
index bf525170f1..8fb56c92b7 100644
--- a/src/lib/libtls/tls_conninfo.c
+++ b/src/lib/libtls/tls_conninfo.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_conninfo.c,v 1.27 2024/03/26 06:31:22 jsing Exp $ */ 1/* $OpenBSD: tls_conninfo.c,v 1.28 2024/12/10 08:40:30 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org> 4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -119,6 +119,14 @@ tls_get_peer_cert_subject(struct tls *ctx, char **subject)
119} 119}
120 120
121static int 121static int
122tls_get_peer_cert_common_name(struct tls *ctx, char **common_name)
123{
124 if (ctx->ssl_peer_cert == NULL)
125 return (-1);
126 return tls_get_common_name(ctx, ctx->ssl_peer_cert, NULL, common_name);
127}
128
129static int
122tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore, 130tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore,
123 time_t *notafter) 131 time_t *notafter)
124{ 132{
@@ -158,6 +166,9 @@ tls_get_peer_cert_info(struct tls *ctx)
158 goto err; 166 goto err;
159 if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1) 167 if (tls_get_peer_cert_issuer(ctx, &ctx->conninfo->issuer) == -1)
160 goto err; 168 goto err;
169 if (tls_get_peer_cert_common_name(ctx,
170 &ctx->conninfo->common_name) == -1)
171 goto err;
161 if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore, 172 if (tls_get_peer_cert_times(ctx, &ctx->conninfo->notbefore,
162 &ctx->conninfo->notafter) == -1) 173 &ctx->conninfo->notafter) == -1)
163 goto err; 174 goto err;
@@ -298,6 +309,7 @@ tls_conninfo_free(struct tls_conninfo *conninfo)
298 free(conninfo->servername); 309 free(conninfo->servername);
299 free(conninfo->version); 310 free(conninfo->version);
300 311
312 free(conninfo->common_name);
301 free(conninfo->hash); 313 free(conninfo->hash);
302 free(conninfo->issuer); 314 free(conninfo->issuer);
303 free(conninfo->subject); 315 free(conninfo->subject);
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index 5ff48ed7c9..8e566a34e0 100644
--- a/src/lib/libtls/tls_internal.h
+++ b/src/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_internal.h,v 1.85 2024/03/26 06:24:52 joshua Exp $ */ 1/* $OpenBSD: tls_internal.h,v 1.86 2024/12/10 08:40:30 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org> 3 * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 4 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -129,6 +129,7 @@ struct tls_conninfo {
129 int session_resumed; 129 int session_resumed;
130 char *version; 130 char *version;
131 131
132 char *common_name;
132 char *hash; 133 char *hash;
133 char *issuer; 134 char *issuer;
134 char *subject; 135 char *subject;
@@ -238,6 +239,8 @@ struct tls_config *tls_config_new_internal(void);
238struct tls *tls_new(void); 239struct tls *tls_new(void);
239struct tls *tls_server_conn(struct tls *ctx); 240struct tls *tls_server_conn(struct tls *ctx);
240 241
242int tls_get_common_name(struct tls *_ctx, X509 *_cert, const char *_in_name,
243 char **_out_common_name);
241int tls_check_name(struct tls *ctx, X509 *cert, const char *servername, 244int tls_check_name(struct tls *ctx, X509 *cert, const char *servername,
242 int *match); 245 int *match);
243int tls_configure_server(struct tls *ctx); 246int tls_configure_server(struct tls *ctx);
diff --git a/src/lib/libtls/tls_peer.c b/src/lib/libtls/tls_peer.c
index ec97a30838..6d63a529f2 100644
--- a/src/lib/libtls/tls_peer.c
+++ b/src/lib/libtls/tls_peer.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_peer.c,v 1.8 2017/04/10 17:11:13 jsing Exp $ */ 1/* $OpenBSD: tls_peer.c,v 1.9 2024/12/10 08:40:30 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org> 4 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
@@ -24,6 +24,14 @@
24#include "tls_internal.h" 24#include "tls_internal.h"
25 25
26const char * 26const char *
27tls_peer_cert_common_name(struct tls *ctx)
28{
29 if (ctx->conninfo == NULL)
30 return (NULL);
31 return (ctx->conninfo->common_name);
32}
33
34const char *
27tls_peer_cert_hash(struct tls *ctx) 35tls_peer_cert_hash(struct tls *ctx)
28{ 36{
29 if (ctx->conninfo == NULL) 37 if (ctx->conninfo == NULL)
diff --git a/src/lib/libtls/tls_verify.c b/src/lib/libtls/tls_verify.c
index 6b2a4fb82a..2935278383 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.31 2024/11/12 22:50:06 tb Exp $ */ 1/* $OpenBSD: tls_verify.c,v 1.32 2024/12/10 08:40:30 tb 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 *
@@ -210,19 +210,22 @@ tls_check_subject_altname(struct tls *ctx, X509 *cert, const char *name,
210} 210}
211 211
212static int 212static int
213tls_check_common_name(struct tls *ctx, X509 *cert, const char *name, 213tls_get_common_name_internal(X509 *cert, char **out_common_name,
214 int *cn_match) 214 unsigned int *out_tlserr, const char **out_errstr)
215{ 215{
216 unsigned char *utf8_bytes = NULL; 216 unsigned char *utf8_bytes = NULL;
217 X509_NAME *subject_name; 217 X509_NAME *subject_name;
218 char *common_name = NULL; 218 char *common_name = NULL;
219 union tls_addr addrbuf;
220 int common_name_len; 219 int common_name_len;
221 ASN1_STRING *data; 220 ASN1_STRING *data;
222 int lastpos = -1; 221 int lastpos = -1;
223 int rv = -1; 222 int rv = -1;
224 223
225 *cn_match = 0; 224 *out_tlserr = TLS_ERROR_UNKNOWN;
225 *out_errstr = "unknown";
226
227 free(*out_common_name);
228 *out_common_name = NULL;
226 229
227 subject_name = X509_get_subject_name(cert); 230 subject_name = X509_get_subject_name(cert);
228 if (subject_name == NULL) 231 if (subject_name == NULL)
@@ -244,10 +247,10 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
244 * more than one CN fed to us in the subject, treating the 247 * more than one CN fed to us in the subject, treating the
245 * certificate as hostile. 248 * certificate as hostile.
246 */ 249 */
247 tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, 250 *out_tlserr = TLS_ERROR_UNKNOWN;
248 "error verifying name '%s': " 251 *out_errstr = "error getting common name: "
249 "Certificate subject contains multiple Common Name fields, " 252 "Certificate subject contains multiple Common Name fields, "
250 "probably a malicious or malformed certificate", name); 253 "probably a malicious or malformed certificate";
251 goto err; 254 goto err;
252 } 255 }
253 256
@@ -257,10 +260,10 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
257 * Fail if we cannot encode the CN bytes as UTF-8. 260 * Fail if we cannot encode the CN bytes as UTF-8.
258 */ 261 */
259 if ((common_name_len = ASN1_STRING_to_UTF8(&utf8_bytes, data)) < 0) { 262 if ((common_name_len = ASN1_STRING_to_UTF8(&utf8_bytes, data)) < 0) {
260 tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, 263 *out_tlserr = TLS_ERROR_UNKNOWN;
261 "error verifying name '%s': " 264 *out_errstr = "error getting common name: "
262 "Common Name field cannot be encoded as a UTF-8 string, " 265 "Common Name field cannot be encoded as a UTF-8 string, "
263 "probably a malicious certificate", name); 266 "probably a malicious certificate";
264 goto err; 267 goto err;
265 } 268 }
266 /* 269 /*
@@ -268,30 +271,85 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
268 * must be between 1 and 64 bytes long. 271 * must be between 1 and 64 bytes long.
269 */ 272 */
270 if (common_name_len < 1 || common_name_len > 64) { 273 if (common_name_len < 1 || common_name_len > 64) {
271 tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, 274 *out_tlserr = TLS_ERROR_UNKNOWN;
272 "error verifying name '%s': " 275 *out_errstr = "error getting common name: "
273 "Common Name field has invalid length, " 276 "Common Name field has invalid length, "
274 "probably a malicious certificate", name); 277 "probably a malicious certificate";
275 goto err; 278 goto err;
276 } 279 }
277 /* 280 /*
278 * Fail if the resulting text contains a NUL byte. 281 * Fail if the resulting text contains a NUL byte.
279 */ 282 */
280 if (memchr(utf8_bytes, 0, common_name_len) != NULL) { 283 if (memchr(utf8_bytes, 0, common_name_len) != NULL) {
281 tls_set_errorx(ctx, TLS_ERROR_UNKNOWN, 284 *out_tlserr = TLS_ERROR_UNKNOWN;
282 "error verifying name '%s': " 285 *out_errstr = "error getting common name: "
283 "NUL byte in Common Name field, " 286 "NUL byte in Common Name field, "
284 "probably a malicious certificate", name); 287 "probably a malicious certificate";
285 goto err; 288 goto err;
286 } 289 }
287 290
288 common_name = strndup(utf8_bytes, common_name_len); 291 common_name = strndup(utf8_bytes, common_name_len);
289 if (common_name == NULL) { 292 if (common_name == NULL) {
290 tls_set_error(ctx, TLS_ERROR_OUT_OF_MEMORY, 293 *out_tlserr = TLS_ERROR_OUT_OF_MEMORY;
291 "out of memory"); 294 *out_errstr = "out of memory";
295 goto err;
296 }
297
298 *out_common_name = common_name;
299 common_name = NULL;
300
301 done:
302 if (*out_common_name == NULL)
303 *out_common_name = strdup("");
304 if (*out_common_name == NULL) {
305 *out_tlserr = TLS_ERROR_OUT_OF_MEMORY;
306 *out_errstr = "out of memory";
292 goto err; 307 goto err;
293 } 308 }
294 309
310 rv = 0;
311
312 err:
313 free(utf8_bytes);
314 free(common_name);
315 return rv;
316}
317
318int
319tls_get_common_name(struct tls *ctx, X509 *cert, const char *in_name,
320 char **out_common_name)
321{
322 unsigned int errcode = TLS_ERROR_UNKNOWN;
323 const char *errstr = "unknown";
324
325 if (tls_get_common_name_internal(cert, out_common_name, &errcode,
326 &errstr) == -1) {
327 const char *name = in_name;
328 const char *space = " ";
329
330 if (name == NULL)
331 name = space = "";
332
333 tls_set_errorx(ctx, errcode, "%s%s%s", name, space, errstr);
334 return -1;
335 }
336
337 return 0;
338}
339
340static int
341tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
342 int *cn_match)
343{
344 char *common_name = NULL;
345 union tls_addr addrbuf;
346 int rv = -1;
347
348 if (tls_get_common_name(ctx, cert, name, &common_name) == -1)
349 goto err;
350 if (strlen(common_name) == 0)
351 goto done;
352
295 /* 353 /*
296 * We don't want to attempt wildcard matching against IP addresses, 354 * We don't want to attempt wildcard matching against IP addresses,
297 * so perform a simple comparison here. 355 * so perform a simple comparison here.
@@ -310,7 +368,6 @@ tls_check_common_name(struct tls *ctx, X509 *cert, const char *name,
310 rv = 0; 368 rv = 0;
311 369
312 err: 370 err:
313 free(utf8_bytes);
314 free(common_name); 371 free(common_name);
315 return rv; 372 return rv;
316} 373}