summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2022-03-17 17:17:58 +0000
committerjsing <>2022-03-17 17:17:58 +0000
commitea581e0232e3466c6e3f461f4c999d8c6cac5a85 (patch)
treef93a102035fa9a93a562a1534dbcdef663f07132 /src/lib
parent9751e52b7d83ea3eaf11922b57b9d55ff0d74ac1 (diff)
downloadopenbsd-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.c35
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}