diff options
author | tb <> | 2021-03-12 15:53:38 +0000 |
---|---|---|
committer | tb <> | 2021-03-12 15:53:38 +0000 |
commit | 36a9d2bef3d172950dafcf87bb1757ae12603547 (patch) | |
tree | a3bddfd82ef9b838d9f033cc9f49fd87d6922a21 /src | |
parent | 292f984699e04c11c217521b43445a995f70fa61 (diff) | |
download | openbsd-36a9d2bef3d172950dafcf87bb1757ae12603547.tar.gz openbsd-36a9d2bef3d172950dafcf87bb1757ae12603547.tar.bz2 openbsd-36a9d2bef3d172950dafcf87bb1757ae12603547.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 | } |