ecstresstest.c: Fix memory leak on error
[openssl.git] / crypto / asn1 / a_i2d_fp.c
1 /*
2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/buffer.h>
13 #include <openssl/asn1.h>
14
15 #ifndef NO_OLD_ASN1
16
17 # ifndef OPENSSL_NO_STDIO
18 int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, const void *x)
19 {
20     BIO *b;
21     int ret;
22
23     if ((b = BIO_new(BIO_s_file())) == NULL) {
24         ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
25         return 0;
26     }
27     BIO_set_fp(b, out, BIO_NOCLOSE);
28     ret = ASN1_i2d_bio(i2d, b, x);
29     BIO_free(b);
30     return ret;
31 }
32 # endif
33
34 int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x)
35 {
36     char *b;
37     unsigned char *p;
38     int i, j = 0, n, ret = 1;
39
40     n = i2d(x, NULL);
41     if (n <= 0)
42         return 0;
43
44     b = OPENSSL_malloc(n);
45     if (b == NULL)
46         return 0;
47
48     p = (unsigned char *)b;
49     i2d(x, &p);
50
51     for (;;) {
52         i = BIO_write(out, &(b[j]), n);
53         if (i == n)
54             break;
55         if (i <= 0) {
56             ret = 0;
57             break;
58         }
59         j += i;
60         n -= i;
61     }
62     OPENSSL_free(b);
63     return ret;
64 }
65
66 #endif
67
68 #ifndef OPENSSL_NO_STDIO
69 int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, const void *x)
70 {
71     BIO *b;
72     int ret;
73
74     if ((b = BIO_new(BIO_s_file())) == NULL) {
75         ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB);
76         return 0;
77     }
78     BIO_set_fp(b, out, BIO_NOCLOSE);
79     ret = ASN1_item_i2d_bio(it, b, x);
80     BIO_free(b);
81     return ret;
82 }
83 #endif
84
85 int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x)
86 {
87     unsigned char *b = NULL;
88     int i, j = 0, n, ret = 1;
89
90     n = ASN1_item_i2d(x, &b, it);
91     if (b == NULL) {
92         ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
93         return 0;
94     }
95
96     for (;;) {
97         i = BIO_write(out, &(b[j]), n);
98         if (i == n)
99             break;
100         if (i <= 0) {
101             ret = 0;
102             break;
103         }
104         j += i;
105         n -= i;
106     }
107     OPENSSL_free(b);
108     return ret;
109 }
110
111 BIO *ASN1_item_i2d_mem_bio(const ASN1_ITEM *it, const ASN1_VALUE *val)
112 {
113     BIO *res;
114
115     if (it == NULL || val == NULL) {
116         ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER);
117         return NULL;
118     }
119
120     if ((res = BIO_new(BIO_s_mem())) == NULL)
121         return NULL;
122     if (ASN1_item_i2d_bio(it, res, val) <= 0) {
123         BIO_free(res);
124         res = NULL;
125     }
126     return res;
127 }