diff options
author | beck <> | 2018-04-06 07:08:20 +0000 |
---|---|---|
committer | beck <> | 2018-04-06 07:08:20 +0000 |
commit | cbd1d6a8808038e6f357e956a343f70ecaf110f4 (patch) | |
tree | 3f536dd9c6701ce8c8c9a5fa0d5c883caa5222e2 /src/lib/libcrypto/x509/x509_vpm.c | |
parent | a0522cf10ae4b806e95c44e85e22fae53f9228d6 (diff) | |
download | openbsd-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/x509_vpm.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509_vpm.c | 69 |
1 files changed, 42 insertions, 27 deletions
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 | ||
127 | static int | 127 | static int |
128 | int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode, | 128 | x509_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 | ||
202 | X509_VERIFY_PARAM * | 202 | X509_VERIFY_PARAM * |
@@ -367,24 +367,28 @@ X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) | |||
367 | } | 367 | } |
368 | 368 | ||
369 | static int | 369 | static int |
370 | int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src, | 370 | x509_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 | |||
505 | X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, | 509 | X509_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 | ||
511 | int | 518 | int |
512 | X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, | 519 | X509_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 | ||
518 | void | 528 | void |
@@ -531,18 +541,25 @@ int | |||
531 | X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, | 541 | X509_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(¶m->id->email, ¶m->id->emaillen, | 544 | if (x509_param_set1_internal(¶m->id->email, ¶m->id->emaillen, |
535 | email, emaillen); | 545 | email, emaillen, 1)) |
546 | return 1; | ||
547 | param->id->poisoned = 1; | ||
548 | return 0; | ||
536 | } | 549 | } |
537 | 550 | ||
538 | int | 551 | int |
539 | X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, | 552 | X509_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 **)¶m->id->ip, ¶m->id->iplen, | 557 | if (x509_param_set1_internal((char **)¶m->id->ip, ¶m->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 | ||
548 | int | 565 | int |
@@ -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 | ||