summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509
diff options
context:
space:
mode:
authorbeck <>2018-04-06 07:08:20 +0000
committerbeck <>2018-04-06 07:08:20 +0000
commitcbd1d6a8808038e6f357e956a343f70ecaf110f4 (patch)
tree3f536dd9c6701ce8c8c9a5fa0d5c883caa5222e2 /src/lib/libcrypto/x509
parenta0522cf10ae4b806e95c44e85e22fae53f9228d6 (diff)
downloadopenbsd-cbd1d6a8808038e6f357e956a343f70ecaf110f4.tar.gz
openbsd-cbd1d6a8808038e6f357e956a343f70ecaf110f4.tar.bz2
openbsd-cbd1d6a8808038e6f357e956a343f70ecaf110f4.zip
poison for X509_VERIFY_PARAM's
Tighten up checks for various X509_VERIFY_PARAM functions, and allow for the verify param to be poisoned (preculding future successful cert validation) if the setting of host, ip, or email for certificate validation fails. (since many callers do not check the return code in the wild and blunder along anyway) Inspired by some discussions with Adam Langley. ok jsing@
Diffstat (limited to 'src/lib/libcrypto/x509')
-rw-r--r--src/lib/libcrypto/x509/vpm_int.h3
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c13
-rw-r--r--src/lib/libcrypto/x509/x509_vpm.c69
3 files changed, 54 insertions, 31 deletions
diff --git a/src/lib/libcrypto/x509/vpm_int.h b/src/lib/libcrypto/x509/vpm_int.h
index 6c8061c847..7fc9fef761 100644
--- a/src/lib/libcrypto/x509/vpm_int.h
+++ b/src/lib/libcrypto/x509/vpm_int.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: vpm_int.h,v 1.3 2016/12/21 15:49:29 jsing Exp $ */ 1/* $OpenBSD: vpm_int.h,v 1.4 2018/04/06 07:08:20 beck Exp $ */
2/* 2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 * 2013. 4 * 2013.
@@ -69,6 +69,7 @@ struct X509_VERIFY_PARAM_ID_st {
69 size_t emaillen; 69 size_t emaillen;
70 unsigned char *ip; /* If not NULL IP address to match */ 70 unsigned char *ip; /* If not NULL IP address to match */
71 size_t iplen; /* Length of IP address */ 71 size_t iplen; /* Length of IP address */
72 int poisoned;
72}; 73};
73 74
74__END_HIDDEN_DECLS 75__END_HIDDEN_DECLS
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index c8ccae5029..8392f509e7 100644
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ b/src/lib/libcrypto/x509/x509_vfy.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_vfy.c,v 1.68 2018/02/22 17:11:30 jsing Exp $ */ 1/* $OpenBSD: x509_vfy.c,v 1.69 2018/04/06 07:08:20 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -182,10 +182,13 @@ check_id_error(X509_STORE_CTX *ctx, int errcode)
182static int 182static int
183check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id) 183check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
184{ 184{
185 size_t i; 185 size_t i, n;
186 size_t n = sk_OPENSSL_STRING_num(id->hosts);
187 char *name; 186 char *name;
188 187
188 if (id->poisoned)
189 return 0;
190
191 n = sk_OPENSSL_STRING_num(id->hosts);
189 free(id->peername); 192 free(id->peername);
190 id->peername = NULL; 193 id->peername = NULL;
191 194
@@ -205,6 +208,10 @@ check_id(X509_STORE_CTX *ctx)
205 X509_VERIFY_PARAM_ID *id = vpm->id; 208 X509_VERIFY_PARAM_ID *id = vpm->id;
206 X509 *x = ctx->cert; 209 X509 *x = ctx->cert;
207 210
211 if (id->poisoned)
212 if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL))
213 return 0;
214
208 if (id->hosts && check_hosts(x, id) <= 0) { 215 if (id->hosts && check_hosts(x, id) <= 0) {
209 if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) 216 if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
210 return 0; 217 return 0;
diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c
index 0897137697..baebcf7bca 100644
--- a/src/lib/libcrypto/x509/x509_vpm.c
+++ b/src/lib/libcrypto/x509/x509_vpm.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_vpm.c,v 1.17 2018/03/22 15:54:46 beck Exp $ */ 1/* $OpenBSD: x509_vpm.c,v 1.18 2018/04/06 07:08:20 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2004. 3 * project 2004.
4 */ 4 */
@@ -125,7 +125,7 @@ sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void)
125} 125}
126 126
127static int 127static int
128int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode, 128x509_param_set_hosts_internal(X509_VERIFY_PARAM_ID *id, int mode,
129 const char *name, size_t namelen) 129 const char *name, size_t namelen)
130{ 130{
131 char *copy; 131 char *copy;
@@ -134,7 +134,6 @@ int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode,
134 namelen = strlen(name); 134 namelen = strlen(name);
135 /* 135 /*
136 * Refuse names with embedded NUL bytes. 136 * Refuse names with embedded NUL bytes.
137 * XXX: Do we need to push an error onto the error stack?
138 */ 137 */
139 if (name && memchr(name, '\0', namelen)) 138 if (name && memchr(name, '\0', namelen))
140 return 0; 139 return 0;
@@ -197,6 +196,7 @@ x509_verify_param_zero(X509_VERIFY_PARAM *param)
197 free(paramid->ip); 196 free(paramid->ip);
198 paramid->ip = NULL; 197 paramid->ip = NULL;
199 paramid->iplen = 0; 198 paramid->iplen = 0;
199 paramid->poisoned = 0;
200} 200}
201 201
202X509_VERIFY_PARAM * 202X509_VERIFY_PARAM *
@@ -367,24 +367,28 @@ X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from)
367} 367}
368 368
369static int 369static int
370int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src, 370x509_param_set1_internal(char **pdest, size_t *pdestlen, const char *src,
371 size_t srclen) 371 size_t srclen, int nonul)
372{ 372{
373 char *tmp; 373 char *tmp;
374 if (src) { 374
375 if (srclen == 0) { 375 if (src == NULL)
376 if ((tmp = strdup(src)) == NULL) 376 return 0;
377 return 0; 377
378 srclen = strlen(src); 378 if (srclen == 0) {
379 } else { 379 srclen = strlen(src);
380 if ((tmp = malloc(srclen)) == NULL) 380 if (srclen == 0)
381 return 0; 381 return 0;
382 memcpy(tmp, src, srclen); 382 if ((tmp = strdup(src)) == NULL)
383 } 383 return 0;
384 } else { 384 } else {
385 tmp = NULL; 385 if (nonul && memchr(src, '\0', srclen))
386 srclen = 0; 386 return 0;
387 if ((tmp = malloc(srclen)) == NULL)
388 return 0;
389 memcpy(tmp, src, srclen);
387 } 390 }
391
388 if (*pdest) 392 if (*pdest)
389 free(*pdest); 393 free(*pdest);
390 *pdest = tmp; 394 *pdest = tmp;
@@ -505,14 +509,20 @@ int
505X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, 509X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
506 const char *name, size_t namelen) 510 const char *name, size_t namelen)
507{ 511{
508 return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen); 512 if (x509_param_set_hosts_internal(param->id, SET_HOST, name, namelen))
513 return 1;
514 param->id->poisoned = 1;
515 return 0;
509} 516}
510 517
511int 518int
512X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, 519X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
513 const char *name, size_t namelen) 520 const char *name, size_t namelen)
514{ 521{
515 return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen); 522 if (x509_param_set_hosts_internal(param->id, ADD_HOST, name, namelen))
523 return 1;
524 param->id->poisoned = 1;
525 return 0;
516} 526}
517 527
518void 528void
@@ -531,18 +541,25 @@ int
531X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, 541X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email,
532 size_t emaillen) 542 size_t emaillen)
533{ 543{
534 return int_x509_param_set1(&param->id->email, &param->id->emaillen, 544 if (x509_param_set1_internal(&param->id->email, &param->id->emaillen,
535 email, emaillen); 545 email, emaillen, 1))
546 return 1;
547 param->id->poisoned = 1;
548 return 0;
536} 549}
537 550
538int 551int
539X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, 552X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip,
540 size_t iplen) 553 size_t iplen)
541{ 554{
542 if (iplen != 0 && iplen != 4 && iplen != 16) 555 if (iplen != 4 && iplen != 16)
543 return 0; 556 goto err;
544 return int_x509_param_set1((char **)&param->id->ip, &param->id->iplen, 557 if (x509_param_set1_internal((char **)&param->id->ip, &param->id->iplen,
545 (char *)ip, iplen); 558 (char *)ip, iplen, 0))
559 return 1;
560 err:
561 param->id->poisoned = 1;
562 return 0;
546} 563}
547 564
548int 565int
@@ -552,8 +569,6 @@ X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
552 size_t iplen; 569 size_t iplen;
553 570
554 iplen = (size_t)a2i_ipadd(ipout, ipasc); 571 iplen = (size_t)a2i_ipadd(ipout, ipasc);
555 if (iplen == 0)
556 return 0;
557 return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); 572 return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
558} 573}
559 574