diff options
author | jsing <> | 2022-03-17 17:17:58 +0000 |
---|---|---|
committer | jsing <> | 2022-03-17 17:17:58 +0000 |
commit | ea581e0232e3466c6e3f461f4c999d8c6cac5a85 (patch) | |
tree | f93a102035fa9a93a562a1534dbcdef663f07132 /src/lib | |
parent | 9751e52b7d83ea3eaf11922b57b9d55ff0d74ac1 (diff) | |
download | openbsd-ea581e0232e3466c6e3f461f4c999d8c6cac5a85.tar.gz openbsd-ea581e0232e3466c6e3f461f4c999d8c6cac5a85.tar.bz2 openbsd-ea581e0232e3466c6e3f461f4c999d8c6cac5a85.zip |
Rework ASN1_STRING_set()
Rework ASN1_STRING_set() so that we always clear and free an existing
allocation, prior to storing the new data. This fixes a number of issues,
including a failure to zero data if the existing allocation was too small.
This also fixes other bugs such as leaving the allocation uninitialised
if NULL is passed for data. Require -1 where strlen() is expected and
improve length and overflow checks.
ok inoguchi@ tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/asn1/a_string.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/src/lib/libcrypto/asn1/a_string.c b/src/lib/libcrypto/asn1/a_string.c index 217d28da09..90e363e9c7 100644 --- a/src/lib/libcrypto/asn1/a_string.c +++ b/src/lib/libcrypto/asn1/a_string.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: a_string.c,v 1.6 2022/03/14 16:35:45 jsing Exp $ */ | 1 | /* $OpenBSD: a_string.c,v 1.7 2022/03/17 17:17:58 jsing 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 | * |
@@ -159,26 +159,33 @@ ASN1_STRING_set(ASN1_STRING *astr, const void *_data, int len) | |||
159 | { | 159 | { |
160 | const char *data = _data; | 160 | const char *data = _data; |
161 | 161 | ||
162 | if (len < 0) { | 162 | if (len == -1) { |
163 | size_t slen; | ||
164 | |||
163 | if (data == NULL) | 165 | if (data == NULL) |
164 | return 0; | 166 | return 0; |
165 | else | 167 | |
166 | len = strlen(data); | 168 | if ((slen = strlen(data)) > INT_MAX) |
167 | } | ||
168 | if ((astr->length < len) || (astr->data == NULL)) { | ||
169 | unsigned char *tmp; | ||
170 | tmp = realloc(astr->data, len + 1); | ||
171 | if (tmp == NULL) { | ||
172 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
173 | return 0; | 169 | return 0; |
174 | } | 170 | |
175 | astr->data = tmp; | 171 | len = (int)slen; |
172 | } | ||
173 | |||
174 | ASN1_STRING_clear(astr); | ||
175 | |||
176 | if (len < 0 || len >= INT_MAX) | ||
177 | return 0; | ||
178 | |||
179 | if ((astr->data = calloc(1, len + 1)) == NULL) { | ||
180 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
181 | return (0); | ||
176 | } | 182 | } |
177 | astr->length = len; | 183 | astr->length = len; |
184 | |||
178 | if (data != NULL) { | 185 | if (data != NULL) { |
179 | memmove(astr->data, data, len); | 186 | memcpy(astr->data, data, len); |
187 | astr->data[len] = '\0'; | ||
180 | } | 188 | } |
181 | astr->data[astr->length] = '\0'; | ||
182 | 189 | ||
183 | return 1; | 190 | return 1; |
184 | } | 191 | } |