diff options
| author | tb <> | 2021-03-12 15:53:38 +0000 |
|---|---|---|
| committer | tb <> | 2021-03-12 15:53:38 +0000 |
| commit | 430ac1ca1c8120f48481984e640aa9977f780961 (patch) | |
| tree | a3bddfd82ef9b838d9f033cc9f49fd87d6922a21 /src | |
| parent | 06b209000b9311573c72169763a57fe69aa0d6c5 (diff) | |
| download | openbsd-430ac1ca1c8120f48481984e640aa9977f780961.tar.gz openbsd-430ac1ca1c8120f48481984e640aa9977f780961.tar.bz2 openbsd-430ac1ca1c8120f48481984e640aa9977f780961.zip | |
Fix checks of memory caps of constraints names
x509_internal.h defines caps on the number of name constraints and
other names (such as subjectAltNames) that we want to allocate per
cert chain. These limits are checked too late. In a particularly
silly cert that jan found on ugos.ugm.ac.id 443, we ended up
allocating six times 2048 x509_constraint_name structures before
deciding that these are more than 512.
Fix this by adding a names_max member to x509_constraints_names which
is set on allocation against which each addition of a name is checked.
cluebat/ok jsing
ok inoguchi on earlier version
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_constraints.c | 34 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 7 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 11 |
3 files changed, 32 insertions, 20 deletions
diff --git a/src/lib/libcrypto/x509/x509_constraints.c b/src/lib/libcrypto/x509/x509_constraints.c index 67cbaa6313..2d55e136d7 100644 --- a/src/lib/libcrypto/x509/x509_constraints.c +++ b/src/lib/libcrypto/x509/x509_constraints.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_constraints.c,v 1.12 2020/11/25 21:17:52 tb Exp $ */ | 1 | /* $OpenBSD: x509_constraints.c,v 1.13 2021/03/12 15:53:38 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -86,9 +86,16 @@ x509_constraints_name_dup(struct x509_constraints_name *name) | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | struct x509_constraints_names * | 88 | struct x509_constraints_names * |
| 89 | x509_constraints_names_new() | 89 | x509_constraints_names_new(size_t names_max) |
| 90 | { | 90 | { |
| 91 | return (calloc(1, sizeof(struct x509_constraints_names))); | 91 | struct x509_constraints_names *new; |
| 92 | |||
| 93 | if ((new = calloc(1, sizeof(struct x509_constraints_names))) == NULL) | ||
| 94 | return NULL; | ||
| 95 | |||
| 96 | new->names_max = names_max; | ||
| 97 | |||
| 98 | return new; | ||
| 92 | } | 99 | } |
| 93 | 100 | ||
| 94 | void | 101 | void |
| @@ -118,6 +125,8 @@ x509_constraints_names_add(struct x509_constraints_names *names, | |||
| 118 | { | 125 | { |
| 119 | size_t i = names->names_count; | 126 | size_t i = names->names_count; |
| 120 | 127 | ||
| 128 | if (names->names_count >= names->names_max) | ||
| 129 | return 0; | ||
| 121 | if (names->names_count == names->names_len) { | 130 | if (names->names_count == names->names_len) { |
| 122 | struct x509_constraints_name **tmp; | 131 | struct x509_constraints_name **tmp; |
| 123 | if ((tmp = recallocarray(names->names, names->names_len, | 132 | if ((tmp = recallocarray(names->names, names->names_len, |
| @@ -141,14 +150,16 @@ x509_constraints_names_dup(struct x509_constraints_names *names) | |||
| 141 | if (names == NULL) | 150 | if (names == NULL) |
| 142 | return NULL; | 151 | return NULL; |
| 143 | 152 | ||
| 144 | if ((new = x509_constraints_names_new()) == NULL) | 153 | if ((new = x509_constraints_names_new(names->names_max)) == NULL) |
| 145 | goto err; | 154 | goto err; |
| 155 | |||
| 146 | for (i = 0; i < names->names_count; i++) { | 156 | for (i = 0; i < names->names_count; i++) { |
| 147 | if ((name = x509_constraints_name_dup(names->names[i])) == NULL) | 157 | if ((name = x509_constraints_name_dup(names->names[i])) == NULL) |
| 148 | goto err; | 158 | goto err; |
| 149 | if (!x509_constraints_names_add(new, name)) | 159 | if (!x509_constraints_names_add(new, name)) |
| 150 | goto err; | 160 | goto err; |
| 151 | } | 161 | } |
| 162 | |||
| 152 | return new; | 163 | return new; |
| 153 | err: | 164 | err: |
| 154 | x509_constraints_names_free(new); | 165 | x509_constraints_names_free(new); |
| @@ -1117,7 +1128,8 @@ x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth) | |||
| 1117 | goto err; | 1128 | goto err; |
| 1118 | if (chain_length == 1) | 1129 | if (chain_length == 1) |
| 1119 | return 1; | 1130 | return 1; |
| 1120 | if ((names = x509_constraints_names_new()) == NULL) { | 1131 | if ((names = x509_constraints_names_new( |
| 1132 | X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) { | ||
| 1121 | verify_err = X509_V_ERR_OUT_OF_MEM; | 1133 | verify_err = X509_V_ERR_OUT_OF_MEM; |
| 1122 | goto err; | 1134 | goto err; |
| 1123 | } | 1135 | } |
| @@ -1130,13 +1142,13 @@ x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth) | |||
| 1130 | if ((cert = sk_X509_value(chain, i)) == NULL) | 1142 | if ((cert = sk_X509_value(chain, i)) == NULL) |
| 1131 | goto err; | 1143 | goto err; |
| 1132 | if (cert->nc != NULL) { | 1144 | if (cert->nc != NULL) { |
| 1133 | if ((permitted = | 1145 | if ((permitted = x509_constraints_names_new( |
| 1134 | x509_constraints_names_new()) == NULL) { | 1146 | X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { |
| 1135 | verify_err = X509_V_ERR_OUT_OF_MEM; | 1147 | verify_err = X509_V_ERR_OUT_OF_MEM; |
| 1136 | goto err; | 1148 | goto err; |
| 1137 | } | 1149 | } |
| 1138 | if ((excluded = | 1150 | if ((excluded = x509_constraints_names_new( |
| 1139 | x509_constraints_names_new()) == NULL) { | 1151 | X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { |
| 1140 | verify_err = X509_V_ERR_OUT_OF_MEM; | 1152 | verify_err = X509_V_ERR_OUT_OF_MEM; |
| 1141 | goto err; | 1153 | goto err; |
| 1142 | } | 1154 | } |
| @@ -1161,10 +1173,6 @@ x509_constraints_chain(STACK_OF(X509) *chain, int *error, int *depth) | |||
| 1161 | if (!x509_constraints_extract_names(names, cert, 0, | 1173 | if (!x509_constraints_extract_names(names, cert, 0, |
| 1162 | &verify_err)) | 1174 | &verify_err)) |
| 1163 | goto err; | 1175 | goto err; |
| 1164 | if (names->names_count > X509_VERIFY_MAX_CHAIN_NAMES) { | ||
| 1165 | verify_err = X509_V_ERR_OUT_OF_MEM; | ||
| 1166 | goto err; | ||
| 1167 | } | ||
| 1168 | } | 1176 | } |
| 1169 | 1177 | ||
| 1170 | x509_constraints_names_free(names); | 1178 | x509_constraints_names_free(names); |
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index 1ede7b6bad..fe40351228 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_internal.h,v 1.6 2021/01/05 16:45:59 jsing Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.7 2021/03/12 15:53:38 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -51,8 +51,9 @@ struct x509_constraints_name { | |||
| 51 | 51 | ||
| 52 | struct x509_constraints_names { | 52 | struct x509_constraints_names { |
| 53 | struct x509_constraints_name **names; | 53 | struct x509_constraints_name **names; |
| 54 | size_t names_len; | ||
| 55 | size_t names_count; | 54 | size_t names_count; |
| 55 | size_t names_len; | ||
| 56 | size_t names_max; | ||
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 58 | struct x509_verify_chain { | 59 | struct x509_verify_chain { |
| @@ -101,7 +102,7 @@ int x509_constraints_names_add(struct x509_constraints_names *names, | |||
| 101 | struct x509_constraints_names *x509_constraints_names_dup( | 102 | struct x509_constraints_names *x509_constraints_names_dup( |
| 102 | struct x509_constraints_names *names); | 103 | struct x509_constraints_names *names); |
| 103 | void x509_constraints_names_clear(struct x509_constraints_names *names); | 104 | void x509_constraints_names_clear(struct x509_constraints_names *names); |
| 104 | struct x509_constraints_names *x509_constraints_names_new(void); | 105 | struct x509_constraints_names *x509_constraints_names_new(size_t names_max); |
| 105 | void x509_constraints_names_free(struct x509_constraints_names *names); | 106 | void x509_constraints_names_free(struct x509_constraints_names *names); |
| 106 | int x509_constraints_valid_host(uint8_t *name, size_t len); | 107 | int x509_constraints_valid_host(uint8_t *name, size_t len); |
| 107 | int x509_constraints_valid_sandns(uint8_t *name, size_t len); | 108 | int x509_constraints_valid_sandns(uint8_t *name, size_t len); |
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index f51ea1d868..3c8369f1f9 100644 --- a/src/lib/libcrypto/x509/x509_verify.c +++ b/src/lib/libcrypto/x509/x509_verify.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_verify.c,v 1.34 2021/02/26 15:19:41 tb Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.35 2021/03/12 15:53:38 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -52,7 +52,8 @@ x509_verify_chain_new(void) | |||
| 52 | if ((chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS, | 52 | if ((chain->cert_errors = calloc(X509_VERIFY_MAX_CHAIN_CERTS, |
| 53 | sizeof(int))) == NULL) | 53 | sizeof(int))) == NULL) |
| 54 | goto err; | 54 | goto err; |
| 55 | if ((chain->names = x509_constraints_names_new()) == NULL) | 55 | if ((chain->names = |
| 56 | x509_constraints_names_new(X509_VERIFY_MAX_CHAIN_NAMES)) == NULL) | ||
| 56 | goto err; | 57 | goto err; |
| 57 | 58 | ||
| 58 | return chain; | 59 | return chain; |
| @@ -720,11 +721,13 @@ x509_verify_validate_constraints(X509 *cert, | |||
| 720 | return 1; | 721 | return 1; |
| 721 | 722 | ||
| 722 | if (cert->nc != NULL) { | 723 | if (cert->nc != NULL) { |
| 723 | if ((permitted = x509_constraints_names_new()) == NULL) { | 724 | if ((permitted = x509_constraints_names_new( |
| 725 | X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { | ||
| 724 | err = X509_V_ERR_OUT_OF_MEM; | 726 | err = X509_V_ERR_OUT_OF_MEM; |
| 725 | goto err; | 727 | goto err; |
| 726 | } | 728 | } |
| 727 | if ((excluded = x509_constraints_names_new()) == NULL) { | 729 | if ((excluded = x509_constraints_names_new( |
| 730 | X509_VERIFY_MAX_CHAIN_CONSTRAINTS)) == NULL) { | ||
| 728 | err = X509_V_ERR_OUT_OF_MEM; | 731 | err = X509_V_ERR_OUT_OF_MEM; |
| 729 | goto err; | 732 | goto err; |
| 730 | } | 733 | } |
