diff options
author | tb <> | 2024-06-18 05:32:38 +0000 |
---|---|---|
committer | tb <> | 2024-06-18 05:32:38 +0000 |
commit | cb1399be72dc293bd666a7a28faac9d470eefa82 (patch) | |
tree | 76cd4d373248a7c18241adc4cbe3ab572ed6fb1a /src | |
parent | 578bd6f0d992036c8ea58704e774ba3e6c585c34 (diff) | |
download | openbsd-cb1399be72dc293bd666a7a28faac9d470eefa82.tar.gz openbsd-cb1399be72dc293bd666a7a28faac9d470eefa82.tar.bz2 openbsd-cb1399be72dc293bd666a7a28faac9d470eefa82.zip |
do_ext_i2d(): avoid leaks and add some missing error checking
If ASN1_OCTET_STRING_new() failed, ext_der would be leaked, fix this.
If i2d(foo, NULL) succeeded, the same is not guaranteed for the second
with appropriately sized buffer since i2d() may make further allocations
internally. So use the proper error check. Also transfer the ownership of
ext_der to the octet string to avoid a now possible double free.
ok jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/x509/x509_conf.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/lib/libcrypto/x509/x509_conf.c b/src/lib/libcrypto/x509/x509_conf.c index 8c4cf5793c..6d611204a5 100644 --- a/src/lib/libcrypto/x509/x509_conf.c +++ b/src/lib/libcrypto/x509/x509_conf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_conf.c,v 1.8 2024/06/18 05:24:24 tb Exp $ */ | 1 | /* $OpenBSD: x509_conf.c,v 1.9 2024/06/18 05:32:38 tb 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 1999. | 3 | * project 1999. |
4 | */ | 4 | */ |
@@ -188,7 +188,7 @@ static X509_EXTENSION * | |||
188 | do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, | 188 | do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, |
189 | void *ext_struc) | 189 | void *ext_struc) |
190 | { | 190 | { |
191 | unsigned char *ext_der; | 191 | unsigned char *ext_der = NULL; |
192 | int ext_len; | 192 | int ext_len; |
193 | ASN1_OCTET_STRING *ext_oct = NULL; | 193 | ASN1_OCTET_STRING *ext_oct = NULL; |
194 | X509_EXTENSION *ext; | 194 | X509_EXTENSION *ext; |
@@ -201,16 +201,21 @@ do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, | |||
201 | goto merr; | 201 | goto merr; |
202 | } else { | 202 | } else { |
203 | unsigned char *p; | 203 | unsigned char *p; |
204 | ext_len = method->i2d(ext_struc, NULL); | 204 | |
205 | if ((ext_len = method->i2d(ext_struc, NULL)) <= 0) | ||
206 | goto merr; | ||
205 | if ((ext_der = malloc(ext_len)) == NULL) | 207 | if ((ext_der = malloc(ext_len)) == NULL) |
206 | goto merr; | 208 | goto merr; |
207 | p = ext_der; | 209 | p = ext_der; |
208 | method->i2d(ext_struc, &p); | 210 | if (method->i2d(ext_struc, &p) != ext_len) |
211 | goto merr; | ||
209 | } | 212 | } |
210 | if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) | 213 | if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) |
211 | goto merr; | 214 | goto merr; |
212 | ext_oct->data = ext_der; | 215 | ext_oct->data = ext_der; |
213 | ext_oct->length = ext_len; | 216 | ext_oct->length = ext_len; |
217 | ext_der = NULL; | ||
218 | ext_len = 0; | ||
214 | 219 | ||
215 | ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); | 220 | ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); |
216 | if (ext == NULL) | 221 | if (ext == NULL) |
@@ -220,6 +225,7 @@ do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, | |||
220 | return ext; | 225 | return ext; |
221 | 226 | ||
222 | merr: | 227 | merr: |
228 | free(ext_der); | ||
223 | ASN1_OCTET_STRING_free(ext_oct); | 229 | ASN1_OCTET_STRING_free(ext_oct); |
224 | X509V3error(ERR_R_MALLOC_FAILURE); | 230 | X509V3error(ERR_R_MALLOC_FAILURE); |
225 | return NULL; | 231 | return NULL; |