Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | | - |
22 | | - |
23 | | - |
24 | | - |
25 | | - |
26 | | - |
27 | | - |
28 | | - |
29 | | - |
30 | | - |
31 | | - |
32 | | - |
33 | | - |
34 | | - |
35 | | - |
36 | | - |
37 | | - |
38 | | - |
39 | | - |
40 | | - |
41 | | - |
42 | | - |
43 | | - |
44 | | - |
45 | | - |
46 | | - |
47 | | - |
48 | | - |
49 | | - |
50 | | - |
51 | | - |
52 | | - |
53 | | - |
54 | | - |
55 | | - |
56 | | - |
57 | | - |
58 | | - |
59 | #include <limits.h> | - |
60 | #include <stdio.h> | - |
61 | | - |
62 | #include <openssl/asn1.h> | - |
63 | #include <openssl/buffer.h> | - |
64 | #include <openssl/err.h> | - |
65 | | - |
66 | static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); | - |
67 | | - |
68 | #ifndef NO_OLD_ASN1 | - |
69 | | - |
70 | void * | - |
71 | ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x) | - |
72 | { | - |
73 | BIO *b; | - |
74 | void *ret; | - |
75 | | - |
76 | if ((b = BIO_new(BIO_s_file())) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
77 | ASN1error(ERR_R_BUF_LIB); | - |
78 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
79 | } | - |
80 | BIO_set_fp(b, in, BIO_NOCLOSE); | - |
81 | ret = ASN1_d2i_bio(xnew, d2i, b, x); | - |
82 | BIO_free(b); | - |
83 | return (ret); never executed: return (ret); | 0 |
84 | } | - |
85 | | - |
86 | void * | - |
87 | ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x) | - |
88 | { | - |
89 | BUF_MEM *b = NULL; | - |
90 | const unsigned char *p; | - |
91 | void *ret = NULL; | - |
92 | int len; | - |
93 | | - |
94 | len = asn1_d2i_read_bio(in, &b); | - |
95 | if (len < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
96 | goto err; never executed: goto err; | 0 |
97 | | - |
98 | p = (unsigned char *)b->data; | - |
99 | ret = d2i(x, &p, len); | - |
100 | | - |
101 | err: code before this statement never executed: err: | 0 |
102 | if (b != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
103 | BUF_MEM_free(b); never executed: BUF_MEM_free(b); | 0 |
104 | return (ret); never executed: return (ret); | 0 |
105 | } | - |
106 | | - |
107 | #endif | - |
108 | | - |
109 | void * | - |
110 | ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) | - |
111 | { | - |
112 | BUF_MEM *b = NULL; | - |
113 | const unsigned char *p; | - |
114 | void *ret = NULL; | - |
115 | int len; | - |
116 | | - |
117 | len = asn1_d2i_read_bio(in, &b); | - |
118 | if (len < 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
119 | goto err; never executed: goto err; | 0 |
120 | | - |
121 | p = (const unsigned char *)b->data; | - |
122 | ret = ASN1_item_d2i(x, &p, len, it); | - |
123 | | - |
124 | err: code before this statement never executed: err: | 0 |
125 | if (b != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
126 | BUF_MEM_free(b); never executed: BUF_MEM_free(b); | 0 |
127 | return (ret); never executed: return (ret); | 0 |
128 | } | - |
129 | | - |
130 | void * | - |
131 | ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) | - |
132 | { | - |
133 | BIO *b; | - |
134 | char *ret; | - |
135 | | - |
136 | if ((b = BIO_new(BIO_s_file())) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
137 | ASN1error(ERR_R_BUF_LIB); | - |
138 | return (NULL); never executed: return ( ((void *)0) ); | 0 |
139 | } | - |
140 | BIO_set_fp(b, in, BIO_NOCLOSE); | - |
141 | ret = ASN1_item_d2i_bio(it, b, x); | - |
142 | BIO_free(b); | - |
143 | return (ret); never executed: return (ret); | 0 |
144 | } | - |
145 | | - |
146 | #define HEADER_SIZE 8 | - |
147 | #define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) | - |
148 | static int | - |
149 | asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) | - |
150 | { | - |
151 | BUF_MEM *b; | - |
152 | unsigned char *p; | - |
153 | int i; | - |
154 | ASN1_const_CTX c; | - |
155 | size_t want = HEADER_SIZE; | - |
156 | int eos = 0; | - |
157 | size_t off = 0; | - |
158 | size_t len = 0; | - |
159 | | - |
160 | b = BUF_MEM_new(); | - |
161 | if (b == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
162 | ASN1error(ERR_R_MALLOC_FAILURE); | - |
163 | return -1; never executed: return -1; | 0 |
164 | } | - |
165 | | - |
166 | ERR_clear_error(); | - |
167 | for (;;) { | - |
168 | if (want >= (len - off)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
169 | want -= (len - off); | - |
170 | | - |
171 | if (len + want < len ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
172 | !BUF_MEM_grow_clean(b, len + want)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
173 | ASN1error(ERR_R_MALLOC_FAILURE); | - |
174 | goto err; never executed: goto err; | 0 |
175 | } | - |
176 | i = BIO_read(in, &(b->data[len]), want); | - |
177 | if ((i < 0) && ((len - off) == 0)) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
178 | ASN1error(ASN1_R_NOT_ENOUGH_DATA); | - |
179 | goto err; never executed: goto err; | 0 |
180 | } | - |
181 | if (i > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
182 | if (len + i < len) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
183 | ASN1error(ASN1_R_TOO_LONG); | - |
184 | goto err; never executed: goto err; | 0 |
185 | } | - |
186 | len += i; | - |
187 | } never executed: end of block | 0 |
188 | } never executed: end of block | 0 |
189 | | - |
190 | | - |
191 | p = (unsigned char *) & (b->data[off]); | - |
192 | c.p = p; | - |
193 | c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), | - |
194 | &(c.xclass), len - off); | - |
195 | if (c.inf & 0x80) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
196 | unsigned long e; | - |
197 | | - |
198 | e = ERR_GET_REASON(ERR_peek_error()); | - |
199 | if (e != ASN1_R_TOO_LONG)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
200 | goto err; never executed: goto err; | 0 |
201 | else | - |
202 | ERR_clear_error(); never executed: ERR_clear_error(); | 0 |
203 | } | - |
204 | i = c.p - p; | - |
205 | off += i; | - |
206 | | - |
207 | if (c.inf & 1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
208 | | - |
209 | eos++; | - |
210 | if (eos < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
211 | ASN1error(ASN1_R_HEADER_TOO_LONG); | - |
212 | goto err; never executed: goto err; | 0 |
213 | } | - |
214 | want = HEADER_SIZE; | - |
215 | } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
216 | | - |
217 | eos--; | - |
218 | if (eos <= 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
219 | break; never executed: break; | 0 |
220 | else | - |
221 | want = HEADER_SIZE; never executed: want = 8; | 0 |
222 | } else { | - |
223 | | - |
224 | want = c.slen; | - |
225 | if (want > (len - off)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
226 | size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; | - |
227 | | - |
228 | want -= (len - off); | - |
229 | if (want > INT_MAX ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
230 | len+want < len) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
231 | ASN1error(ASN1_R_TOO_LONG); | - |
232 | goto err; never executed: goto err; | 0 |
233 | } | - |
234 | while (want > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
235 | | - |
236 | | - |
237 | | - |
238 | | - |
239 | | - |
240 | | - |
241 | size_t chunk = want > chunk_max ? chunk_max : want;TRUE | never evaluated | FALSE | never evaluated |
| 0 |
242 | | - |
243 | if (!BUF_MEM_grow_clean(b, len + chunk)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
244 | ASN1error(ERR_R_MALLOC_FAILURE); | - |
245 | goto err; never executed: goto err; | 0 |
246 | } | - |
247 | want -= chunk; | - |
248 | while (chunk > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
249 | i = BIO_read(in, &(b->data[len]), chunk); | - |
250 | if (i <= 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
251 | ASN1error(ASN1_R_NOT_ENOUGH_DATA); | - |
252 | goto err; never executed: goto err; | 0 |
253 | } | - |
254 | | - |
255 | | - |
256 | | - |
257 | | - |
258 | len += i; | - |
259 | chunk -= i; | - |
260 | } never executed: end of block | 0 |
261 | if (chunk_max < INT_MAX/2)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
262 | chunk_max *= 2; never executed: chunk_max *= 2; | 0 |
263 | } never executed: end of block | 0 |
264 | } never executed: end of block | 0 |
265 | if (off + c.slen < off) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
266 | ASN1error(ASN1_R_TOO_LONG); | - |
267 | goto err; never executed: goto err; | 0 |
268 | } | - |
269 | off += c.slen; | - |
270 | if (eos <= 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
271 | break; never executed: break; | 0 |
272 | } else | - |
273 | want = HEADER_SIZE; never executed: want = 8; | 0 |
274 | } | - |
275 | } | - |
276 | | - |
277 | if (off > INT_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
278 | ASN1error(ASN1_R_TOO_LONG); | - |
279 | goto err; never executed: goto err; | 0 |
280 | } | - |
281 | | - |
282 | *pb = b; | - |
283 | return off; never executed: return off; | 0 |
284 | | - |
285 | err: | - |
286 | if (b != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
287 | BUF_MEM_free(b); never executed: BUF_MEM_free(b); | 0 |
288 | return -1; never executed: return -1; | 0 |
289 | } | - |
| | |