File: | out/../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c |
Warning: | line 634, column 22 Access to field 'encode' results in a dereference of a null pointer (loaded from variable 'current_encoder') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * Copyright 2019-2022 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 <openssl/core_names.h> | |||
11 | #include <openssl/bio.h> | |||
12 | #include <openssl/encoder.h> | |||
13 | #include <openssl/buffer.h> | |||
14 | #include <openssl/params.h> | |||
15 | #include <openssl/provider.h> | |||
16 | #include <openssl/trace.h> | |||
17 | #include "internal/bio.h" | |||
18 | #include "internal/provider.h" | |||
19 | #include "encoder_local.h" | |||
20 | ||||
21 | struct encoder_process_data_st { | |||
22 | OSSL_ENCODER_CTX *ctx; | |||
23 | ||||
24 | /* Current BIO */ | |||
25 | BIO *bio; | |||
26 | ||||
27 | /* Index of the current encoder instance to be processed */ | |||
28 | int current_encoder_inst_index; | |||
29 | ||||
30 | /* Processing data passed down through recursion */ | |||
31 | int level; /* Recursion level */ | |||
32 | OSSL_ENCODER_INSTANCE *next_encoder_inst; | |||
33 | int count_output_structure; | |||
34 | ||||
35 | /* Processing data passed up through recursion */ | |||
36 | OSSL_ENCODER_INSTANCE *prev_encoder_inst; | |||
37 | unsigned char *running_output; | |||
38 | size_t running_output_length; | |||
39 | /* Data type = the name of the first succeeding encoder implementation */ | |||
40 | const char *data_type; | |||
41 | }; | |||
42 | ||||
43 | static int encoder_process(struct encoder_process_data_st *data); | |||
44 | ||||
45 | int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out) | |||
46 | { | |||
47 | struct encoder_process_data_st data; | |||
48 | ||||
49 | memset(&data, 0, sizeof(data)); | |||
50 | data.ctx = ctx; | |||
51 | data.bio = out; | |||
52 | data.current_encoder_inst_index = OSSL_ENCODER_CTX_get_num_encoders(ctx); | |||
53 | ||||
54 | if (data.current_encoder_inst_index == 0) { | |||
55 | ERR_raise_data(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,55,__func__), ERR_set_error)(ERR_LIB_OSSL_ENCODER59, OSSL_ENCODER_R_ENCODER_NOT_FOUND101, | |||
56 | "No encoders were found. For standard encoders you need " | |||
57 | "at least one of the default or base providers " | |||
58 | "available. Did you forget to load them?"); | |||
59 | return 0; | |||
60 | } | |||
61 | ||||
62 | return encoder_process(&data) > 0; | |||
63 | } | |||
64 | ||||
65 | #ifndef OPENSSL_NO_STDIO | |||
66 | static BIO *bio_from_file(FILE *fp) | |||
67 | { | |||
68 | BIO *b; | |||
69 | ||||
70 | if ((b = BIO_new(BIO_s_file())) == NULL((void*)0)) { | |||
71 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_BUF_LIB)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,71,__func__), ERR_set_error)((59),((7 | (0x2 << 18L))) ,((void*)0)); | |||
72 | return NULL((void*)0); | |||
73 | } | |||
74 | BIO_set_fp(b, fp, BIO_NOCLOSE)BIO_ctrl(b,106,0x00,(char *)(fp)); | |||
75 | return b; | |||
76 | } | |||
77 | ||||
78 | int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp) | |||
79 | { | |||
80 | BIO *b = bio_from_file(fp); | |||
81 | int ret = 0; | |||
82 | ||||
83 | if (b != NULL((void*)0)) | |||
84 | ret = OSSL_ENCODER_to_bio(ctx, b); | |||
85 | ||||
86 | BIO_free(b); | |||
87 | return ret; | |||
88 | } | |||
89 | #endif | |||
90 | ||||
91 | int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata, | |||
92 | size_t *pdata_len) | |||
93 | { | |||
94 | BIO *out; | |||
95 | BUF_MEM *buf = NULL((void*)0); | |||
96 | int ret = 0; | |||
97 | ||||
98 | if (pdata_len == NULL((void*)0)) { | |||
| ||||
99 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,99,__func__), ERR_set_error)((59),((258|((0x1 << 18L)| (0x2 << 18L)))),((void*)0)); | |||
100 | return 0; | |||
101 | } | |||
102 | ||||
103 | out = BIO_new(BIO_s_mem()); | |||
104 | ||||
105 | if (out != NULL((void*)0) | |||
106 | && OSSL_ENCODER_to_bio(ctx, out) | |||
107 | && BIO_get_mem_ptr(out, &buf)BIO_ctrl(out,115,0, (char *)(&buf)) > 0) { | |||
108 | ret = 1; /* Hope for the best. A too small buffer will clear this */ | |||
109 | ||||
110 | if (pdata != NULL((void*)0) && *pdata != NULL((void*)0)) { | |||
111 | if (*pdata_len < buf->length) | |||
112 | /* | |||
113 | * It's tempting to do |*pdata_len = (size_t)buf->length| | |||
114 | * However, it's believed to be confusing more than helpful, | |||
115 | * so we don't. | |||
116 | */ | |||
117 | ret = 0; | |||
118 | else | |||
119 | *pdata_len -= buf->length; | |||
120 | } else { | |||
121 | /* The buffer with the right size is already allocated for us */ | |||
122 | *pdata_len = (size_t)buf->length; | |||
123 | } | |||
124 | ||||
125 | if (ret) { | |||
126 | if (pdata != NULL((void*)0)) { | |||
127 | if (*pdata != NULL((void*)0)) { | |||
128 | memcpy(*pdata, buf->data, buf->length); | |||
129 | *pdata += buf->length; | |||
130 | } else { | |||
131 | /* In this case, we steal the data from BIO_s_mem() */ | |||
132 | *pdata = (unsigned char *)buf->data; | |||
133 | buf->data = NULL((void*)0); | |||
134 | } | |||
135 | } | |||
136 | } | |||
137 | } | |||
138 | BIO_free(out); | |||
139 | return ret; | |||
140 | } | |||
141 | ||||
142 | int OSSL_ENCODER_CTX_set_selection(OSSL_ENCODER_CTX *ctx, int selection) | |||
143 | { | |||
144 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0)) { | |||
145 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,145,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
146 | return 0; | |||
147 | } | |||
148 | ||||
149 | if (!ossl_assert(selection != 0)((selection != 0) != 0)) { | |||
150 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,150,__func__), ERR_set_error)((59),((262|(0x2 << 18L)) ),((void*)0)); | |||
151 | return 0; | |||
152 | } | |||
153 | ||||
154 | ctx->selection = selection; | |||
155 | return 1; | |||
156 | } | |||
157 | ||||
158 | int OSSL_ENCODER_CTX_set_output_type(OSSL_ENCODER_CTX *ctx, | |||
159 | const char *output_type) | |||
160 | { | |||
161 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0) || !ossl_assert(output_type != NULL)((output_type != ((void*)0)) != 0)) { | |||
162 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,162,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
163 | return 0; | |||
164 | } | |||
165 | ||||
166 | ctx->output_type = output_type; | |||
167 | return 1; | |||
168 | } | |||
169 | ||||
170 | int OSSL_ENCODER_CTX_set_output_structure(OSSL_ENCODER_CTX *ctx, | |||
171 | const char *output_structure) | |||
172 | { | |||
173 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0) || !ossl_assert(output_structure != NULL)((output_structure != ((void*)0)) != 0)) { | |||
174 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,174,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
175 | return 0; | |||
176 | } | |||
177 | ||||
178 | ctx->output_structure = output_structure; | |||
179 | return 1; | |||
180 | } | |||
181 | ||||
182 | static OSSL_ENCODER_INSTANCE *ossl_encoder_instance_new(OSSL_ENCODER *encoder, | |||
183 | void *encoderctx) | |||
184 | { | |||
185 | OSSL_ENCODER_INSTANCE *encoder_inst = NULL((void*)0); | |||
186 | const OSSL_PROVIDER *prov; | |||
187 | OSSL_LIB_CTX *libctx; | |||
188 | const OSSL_PROPERTY_LIST *props; | |||
189 | const OSSL_PROPERTY_DEFINITION *prop; | |||
190 | ||||
191 | if (!ossl_assert(encoder != NULL)((encoder != ((void*)0)) != 0)) { | |||
192 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,192,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
193 | return 0; | |||
194 | } | |||
195 | ||||
196 | if ((encoder_inst = OPENSSL_zalloc(sizeof(*encoder_inst))CRYPTO_zalloc(sizeof(*encoder_inst), "../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" , 196)) == NULL((void*)0)) { | |||
197 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,197,__func__), ERR_set_error)((59),((256|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
198 | return 0; | |||
199 | } | |||
200 | ||||
201 | if (!OSSL_ENCODER_up_ref(encoder)) { | |||
202 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,202,__func__), ERR_set_error)((59),((259|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
203 | goto err; | |||
204 | } | |||
205 | ||||
206 | prov = OSSL_ENCODER_get0_provider(encoder); | |||
207 | libctx = ossl_provider_libctx(prov); | |||
208 | props = ossl_encoder_parsed_properties(encoder); | |||
209 | if (props == NULL((void*)0)) { | |||
210 | ERR_raise_data(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,210,__func__), ERR_set_error)(ERR_LIB_OSSL_DECODER60, ERR_R_INVALID_PROPERTY_DEFINITION(270|(0x2 << 18L)), | |||
211 | "there are no property definitions with encoder %s", | |||
212 | OSSL_ENCODER_get0_name(encoder)); | |||
213 | goto err; | |||
214 | } | |||
215 | ||||
216 | /* The "output" property is mandatory */ | |||
217 | prop = ossl_property_find_property(props, libctx, "output"); | |||
218 | encoder_inst->output_type = ossl_property_get_string_value(libctx, prop); | |||
219 | if (encoder_inst->output_type == NULL((void*)0)) { | |||
220 | ERR_raise_data(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,220,__func__), ERR_set_error)(ERR_LIB_OSSL_DECODER60, ERR_R_INVALID_PROPERTY_DEFINITION(270|(0x2 << 18L)), | |||
221 | "the mandatory 'output' property is missing " | |||
222 | "for encoder %s (properties: %s)", | |||
223 | OSSL_ENCODER_get0_name(encoder), | |||
224 | OSSL_ENCODER_get0_properties(encoder)); | |||
225 | goto err; | |||
226 | } | |||
227 | ||||
228 | /* The "structure" property is optional */ | |||
229 | prop = ossl_property_find_property(props, libctx, "structure"); | |||
230 | if (prop != NULL((void*)0)) | |||
231 | encoder_inst->output_structure | |||
232 | = ossl_property_get_string_value(libctx, prop); | |||
233 | ||||
234 | encoder_inst->encoder = encoder; | |||
235 | encoder_inst->encoderctx = encoderctx; | |||
236 | return encoder_inst; | |||
237 | err: | |||
238 | ossl_encoder_instance_free(encoder_inst); | |||
239 | return NULL((void*)0); | |||
240 | } | |||
241 | ||||
242 | void ossl_encoder_instance_free(OSSL_ENCODER_INSTANCE *encoder_inst) | |||
243 | { | |||
244 | if (encoder_inst != NULL((void*)0)) { | |||
245 | if (encoder_inst->encoder != NULL((void*)0)) | |||
246 | encoder_inst->encoder->freectx(encoder_inst->encoderctx); | |||
247 | encoder_inst->encoderctx = NULL((void*)0); | |||
248 | OSSL_ENCODER_free(encoder_inst->encoder); | |||
249 | encoder_inst->encoder = NULL((void*)0); | |||
250 | OPENSSL_free(encoder_inst)CRYPTO_free(encoder_inst, "../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" , 250); | |||
251 | } | |||
252 | } | |||
253 | ||||
254 | static int ossl_encoder_ctx_add_encoder_inst(OSSL_ENCODER_CTX *ctx, | |||
255 | OSSL_ENCODER_INSTANCE *ei) | |||
256 | { | |||
257 | int ok; | |||
258 | ||||
259 | if (ctx->encoder_insts == NULL((void*)0) | |||
260 | && (ctx->encoder_insts = | |||
261 | sk_OSSL_ENCODER_INSTANCE_new_null()) == NULL((void*)0)) { | |||
262 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,262,__func__), ERR_set_error)((59),((256|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
263 | return 0; | |||
264 | } | |||
265 | ||||
266 | ok = (sk_OSSL_ENCODER_INSTANCE_push(ctx->encoder_insts, ei) > 0); | |||
267 | if (ok) { | |||
268 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
269 | BIO_printf(trc_out, | |||
270 | "(ctx %p) Added encoder instance %p (encoder %p):\n" | |||
271 | " %s with %s\n", | |||
272 | (void *)ctx, (void *)ei, (void *)ei->encoder, | |||
273 | OSSL_ENCODER_get0_name(ei->encoder), | |||
274 | OSSL_ENCODER_get0_properties(ei->encoder)); | |||
275 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
276 | } | |||
277 | return ok; | |||
278 | } | |||
279 | ||||
280 | int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder) | |||
281 | { | |||
282 | OSSL_ENCODER_INSTANCE *encoder_inst = NULL((void*)0); | |||
283 | const OSSL_PROVIDER *prov = NULL((void*)0); | |||
284 | void *encoderctx = NULL((void*)0); | |||
285 | void *provctx = NULL((void*)0); | |||
286 | ||||
287 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0) || !ossl_assert(encoder != NULL)((encoder != ((void*)0)) != 0)) { | |||
288 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,288,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
289 | return 0; | |||
290 | } | |||
291 | ||||
292 | prov = OSSL_ENCODER_get0_provider(encoder); | |||
293 | provctx = OSSL_PROVIDER_get0_provider_ctx(prov); | |||
294 | ||||
295 | if ((encoderctx = encoder->newctx(provctx)) == NULL((void*)0) | |||
296 | || (encoder_inst = | |||
297 | ossl_encoder_instance_new(encoder, encoderctx)) == NULL((void*)0)) | |||
298 | goto err; | |||
299 | /* Avoid double free of encoderctx on further errors */ | |||
300 | encoderctx = NULL((void*)0); | |||
301 | ||||
302 | if (!ossl_encoder_ctx_add_encoder_inst(ctx, encoder_inst)) | |||
303 | goto err; | |||
304 | ||||
305 | return 1; | |||
306 | err: | |||
307 | ossl_encoder_instance_free(encoder_inst); | |||
308 | if (encoderctx != NULL((void*)0)) | |||
309 | encoder->freectx(encoderctx); | |||
310 | return 0; | |||
311 | } | |||
312 | ||||
313 | int OSSL_ENCODER_CTX_add_extra(OSSL_ENCODER_CTX *ctx, | |||
314 | OSSL_LIB_CTX *libctx, const char *propq) | |||
315 | { | |||
316 | return 1; | |||
317 | } | |||
318 | ||||
319 | int OSSL_ENCODER_CTX_get_num_encoders(OSSL_ENCODER_CTX *ctx) | |||
320 | { | |||
321 | if (ctx == NULL((void*)0) || ctx->encoder_insts == NULL((void*)0)) | |||
322 | return 0; | |||
323 | return sk_OSSL_ENCODER_INSTANCE_num(ctx->encoder_insts); | |||
324 | } | |||
325 | ||||
326 | int OSSL_ENCODER_CTX_set_construct(OSSL_ENCODER_CTX *ctx, | |||
327 | OSSL_ENCODER_CONSTRUCT *construct) | |||
328 | { | |||
329 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0)) { | |||
330 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,330,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
331 | return 0; | |||
332 | } | |||
333 | ctx->construct = construct; | |||
334 | return 1; | |||
335 | } | |||
336 | ||||
337 | int OSSL_ENCODER_CTX_set_construct_data(OSSL_ENCODER_CTX *ctx, | |||
338 | void *construct_data) | |||
339 | { | |||
340 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0)) { | |||
341 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,341,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
342 | return 0; | |||
343 | } | |||
344 | ctx->construct_data = construct_data; | |||
345 | return 1; | |||
346 | } | |||
347 | ||||
348 | int OSSL_ENCODER_CTX_set_cleanup(OSSL_ENCODER_CTX *ctx, | |||
349 | OSSL_ENCODER_CLEANUP *cleanup) | |||
350 | { | |||
351 | if (!ossl_assert(ctx != NULL)((ctx != ((void*)0)) != 0)) { | |||
352 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,352,__func__), ERR_set_error)((59),((258|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
353 | return 0; | |||
354 | } | |||
355 | ctx->cleanup = cleanup; | |||
356 | return 1; | |||
357 | } | |||
358 | ||||
359 | OSSL_ENCODER * | |||
360 | OSSL_ENCODER_INSTANCE_get_encoder(OSSL_ENCODER_INSTANCE *encoder_inst) | |||
361 | { | |||
362 | if (encoder_inst == NULL((void*)0)) | |||
363 | return NULL((void*)0); | |||
364 | return encoder_inst->encoder; | |||
365 | } | |||
366 | ||||
367 | void * | |||
368 | OSSL_ENCODER_INSTANCE_get_encoder_ctx(OSSL_ENCODER_INSTANCE *encoder_inst) | |||
369 | { | |||
370 | if (encoder_inst == NULL((void*)0)) | |||
371 | return NULL((void*)0); | |||
372 | return encoder_inst->encoderctx; | |||
373 | } | |||
374 | ||||
375 | const char * | |||
376 | OSSL_ENCODER_INSTANCE_get_output_type(OSSL_ENCODER_INSTANCE *encoder_inst) | |||
377 | { | |||
378 | if (encoder_inst == NULL((void*)0)) | |||
379 | return NULL((void*)0); | |||
380 | return encoder_inst->output_type; | |||
381 | } | |||
382 | ||||
383 | const char * | |||
384 | OSSL_ENCODER_INSTANCE_get_output_structure(OSSL_ENCODER_INSTANCE *encoder_inst) | |||
385 | { | |||
386 | if (encoder_inst == NULL((void*)0)) | |||
387 | return NULL((void*)0); | |||
388 | return encoder_inst->output_structure; | |||
389 | } | |||
390 | ||||
391 | static int encoder_process(struct encoder_process_data_st *data) | |||
392 | { | |||
393 | OSSL_ENCODER_INSTANCE *current_encoder_inst = NULL((void*)0); | |||
394 | OSSL_ENCODER *current_encoder = NULL((void*)0); | |||
395 | OSSL_ENCODER_CTX *current_encoder_ctx = NULL((void*)0); | |||
396 | BIO *allocated_out = NULL((void*)0); | |||
397 | const void *original_data = NULL((void*)0); | |||
398 | OSSL_PARAM abstract[10]; | |||
399 | const OSSL_PARAM *current_abstract = NULL((void*)0); | |||
400 | int i; | |||
401 | int ok = -1; /* -1 signifies that the lookup loop gave nothing */ | |||
402 | int top = 0; | |||
403 | ||||
404 | if (data->next_encoder_inst
| |||
405 | /* First iteration, where we prepare for what is to come */ | |||
406 | ||||
407 | data->count_output_structure = | |||
408 | data->ctx->output_structure == NULL((void*)0) ? -1 : 0; | |||
409 | top = 1; | |||
410 | } | |||
411 | ||||
412 | for (i = data->current_encoder_inst_index; i-- > 0;) { | |||
413 | OSSL_ENCODER *next_encoder = NULL((void*)0); | |||
414 | const char *current_output_type; | |||
415 | const char *current_output_structure; | |||
416 | struct encoder_process_data_st new_data; | |||
417 | ||||
418 | if (!top) | |||
419 | next_encoder = | |||
420 | OSSL_ENCODER_INSTANCE_get_encoder(data->next_encoder_inst); | |||
421 | ||||
422 | current_encoder_inst = | |||
423 | sk_OSSL_ENCODER_INSTANCE_value(data->ctx->encoder_insts, i); | |||
424 | current_encoder = | |||
425 | OSSL_ENCODER_INSTANCE_get_encoder(current_encoder_inst); | |||
426 | current_encoder_ctx = | |||
427 | OSSL_ENCODER_INSTANCE_get_encoder_ctx(current_encoder_inst); | |||
428 | current_output_type = | |||
429 | OSSL_ENCODER_INSTANCE_get_output_type(current_encoder_inst); | |||
430 | current_output_structure = | |||
431 | OSSL_ENCODER_INSTANCE_get_output_structure(current_encoder_inst); | |||
432 | memset(&new_data, 0, sizeof(new_data)); | |||
433 | new_data.ctx = data->ctx; | |||
434 | new_data.current_encoder_inst_index = i; | |||
435 | new_data.next_encoder_inst = current_encoder_inst; | |||
436 | new_data.count_output_structure = data->count_output_structure; | |||
437 | new_data.level = data->level + 1; | |||
438 | ||||
439 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
440 | BIO_printf(trc_out, | |||
441 | "[%d] (ctx %p) Considering encoder instance %p (encoder %p)\n", | |||
442 | data->level, (void *)data->ctx, | |||
443 | (void *)current_encoder_inst, (void *)current_encoder); | |||
444 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
445 | ||||
446 | /* | |||
447 | * If this is the top call, we check if the output type of the current | |||
448 | * encoder matches the desired output type. | |||
449 | * If this isn't the top call, i.e. this is deeper in the recursion, | |||
450 | * we instead check if the output type of the current encoder matches | |||
451 | * the name of the next encoder (the one found by the parent call). | |||
452 | */ | |||
453 | if (top) { | |||
454 | if (data->ctx->output_type != NULL((void*)0) | |||
455 | && OPENSSL_strcasecmp(current_output_type, | |||
456 | data->ctx->output_type) != 0) { | |||
457 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
458 | BIO_printf(trc_out, | |||
459 | "[%d] Skipping because current encoder output type (%s) != desired output type (%s)\n", | |||
460 | data->level, | |||
461 | current_output_type, data->ctx->output_type); | |||
462 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
463 | continue; | |||
464 | } | |||
465 | } else { | |||
466 | if (!OSSL_ENCODER_is_a(next_encoder, current_output_type)) { | |||
467 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
468 | BIO_printf(trc_out, | |||
469 | "[%d] Skipping because current encoder output type (%s) != name of encoder %p\n", | |||
470 | data->level, | |||
471 | current_output_type, (void *)next_encoder); | |||
472 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
473 | continue; | |||
474 | } | |||
475 | } | |||
476 | ||||
477 | /* | |||
478 | * If the caller and the current encoder specify an output structure, | |||
479 | * Check if they match. If they do, count the match, otherwise skip | |||
480 | * the current encoder. | |||
481 | */ | |||
482 | if (data->ctx->output_structure != NULL((void*)0) | |||
483 | && current_output_structure != NULL((void*)0)) { | |||
484 | if (OPENSSL_strcasecmp(data->ctx->output_structure, | |||
485 | current_output_structure) != 0) { | |||
486 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
487 | BIO_printf(trc_out, | |||
488 | "[%d] Skipping because current encoder output structure (%s) != ctx output structure (%s)\n", | |||
489 | data->level, | |||
490 | current_output_structure, | |||
491 | data->ctx->output_structure); | |||
492 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
493 | continue; | |||
494 | } | |||
495 | ||||
496 | data->count_output_structure++; | |||
497 | } | |||
498 | ||||
499 | /* | |||
500 | * Recurse to process the encoder implementations before the current | |||
501 | * one. | |||
502 | */ | |||
503 | ok = encoder_process(&new_data); | |||
504 | ||||
505 | data->prev_encoder_inst = new_data.prev_encoder_inst; | |||
506 | data->running_output = new_data.running_output; | |||
507 | data->running_output_length = new_data.running_output_length; | |||
508 | ||||
509 | /* | |||
510 | * ok == -1 means that the recursion call above gave no further | |||
511 | * encoders, and that the one we're currently at should | |||
512 | * be tried. | |||
513 | * ok == 0 means that something failed in the recursion call | |||
514 | * above, making the result unsuitable for a chain. | |||
515 | * In this case, we simply continue to try finding a | |||
516 | * suitable encoder at this recursion level. | |||
517 | * ok == 1 means that the recursion call was successful, and we | |||
518 | * try to use the result at this recursion level. | |||
519 | */ | |||
520 | if (ok != 0) | |||
521 | break; | |||
522 | ||||
523 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
524 | BIO_printf(trc_out, | |||
525 | "[%d] Skipping because recusion level %d failed\n", | |||
526 | data->level, new_data.level); | |||
527 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
528 | } | |||
529 | ||||
530 | /* | |||
531 | * If |i < 0|, we didn't find any useful encoder in this recursion, so | |||
532 | * we do the rest of the process only if |i >= 0|. | |||
533 | */ | |||
534 | if (i < 0) { | |||
535 | ok = -1; | |||
536 | ||||
537 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
538 | BIO_printf(trc_out, | |||
539 | "[%d] (ctx %p) No suitable encoder found\n", | |||
540 | data->level, (void *)data->ctx); | |||
541 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
542 | } else { | |||
543 | /* Preparations */ | |||
544 | ||||
545 | switch (ok) { | |||
546 | case 0: | |||
547 | break; | |||
548 | case -1: | |||
549 | /* | |||
550 | * We have reached the beginning of the encoder instance sequence, | |||
551 | * so we prepare the object to be encoded. | |||
552 | */ | |||
553 | ||||
554 | /* | |||
555 | * |data->count_output_structure| is one of these values: | |||
556 | * | |||
557 | * -1 There is no desired output structure | |||
558 | * 0 There is a desired output structure, and it wasn't | |||
559 | * matched by any of the encoder instances that were | |||
560 | * considered | |||
561 | * >0 There is a desired output structure, and at least one | |||
562 | * of the encoder instances matched it | |||
563 | */ | |||
564 | if (data->count_output_structure
| |||
565 | return 0; | |||
566 | ||||
567 | original_data = | |||
568 | data->ctx->construct(current_encoder_inst, | |||
569 | data->ctx->construct_data); | |||
570 | ||||
571 | /* Also set the data type, using the encoder implementation name */ | |||
572 | data->data_type = OSSL_ENCODER_get0_name(current_encoder); | |||
573 | ||||
574 | /* Assume that the constructor recorded an error */ | |||
575 | if (original_data != NULL((void*)0)) | |||
576 | ok = 1; | |||
577 | else | |||
578 | ok = 0; | |||
579 | break; | |||
580 | case 1: | |||
581 | if (!ossl_assert(data->running_output != NULL)((data->running_output != ((void*)0)) != 0)) { | |||
582 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" ,582,__func__), ERR_set_error)((59),((259|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); | |||
583 | ok = 0; | |||
584 | break; | |||
585 | } | |||
586 | ||||
587 | { | |||
588 | /* | |||
589 | * Create an object abstraction from the latest output, which | |||
590 | * was stolen from the previous round. | |||
591 | */ | |||
592 | ||||
593 | OSSL_PARAM *abstract_p = abstract; | |||
594 | const char *prev_output_structure = | |||
595 | OSSL_ENCODER_INSTANCE_get_output_structure(data->prev_encoder_inst); | |||
596 | ||||
597 | *abstract_p++ = | |||
598 | OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE"data-type", | |||
599 | (char *)data->data_type, 0); | |||
600 | if (prev_output_structure != NULL((void*)0)) | |||
601 | *abstract_p++ = | |||
602 | OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE"data-structure", | |||
603 | (char *)prev_output_structure, | |||
604 | 0); | |||
605 | *abstract_p++ = | |||
606 | OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA"data", | |||
607 | data->running_output, | |||
608 | data->running_output_length); | |||
609 | *abstract_p = OSSL_PARAM_construct_end(); | |||
610 | current_abstract = abstract; | |||
611 | } | |||
612 | break; | |||
613 | } | |||
614 | ||||
615 | /* Calling the encoder implementation */ | |||
616 | ||||
617 | if (ok
| |||
618 | OSSL_CORE_BIO *cbio = NULL((void*)0); | |||
619 | BIO *current_out = NULL((void*)0); | |||
620 | ||||
621 | /* | |||
622 | * If we're at the last encoder instance to use, we're setting up | |||
623 | * final output. Otherwise, set up an intermediary memory output. | |||
624 | */ | |||
625 | if (top
| |||
626 | current_out = data->bio; | |||
627 | else if ((current_out = allocated_out = BIO_new(BIO_s_mem())) | |||
628 | == NULL((void*)0)) | |||
629 | ok = 0; /* Assume BIO_new() recorded an error */ | |||
630 | ||||
631 | if (ok
| |||
632 | ok = (cbio = ossl_core_bio_new_from_bio(current_out)) != NULL((void*)0); | |||
633 | if (ok
| |||
634 | ok = current_encoder->encode(current_encoder_ctx, cbio, | |||
| ||||
635 | original_data, current_abstract, | |||
636 | data->ctx->selection, | |||
637 | ossl_pw_passphrase_callback_enc, | |||
638 | &data->ctx->pwdata); | |||
639 | OSSL_TRACE_BEGIN(ENCODER)do { BIO *trc_out = ((void*)0); if (0) { | |||
640 | BIO_printf(trc_out, | |||
641 | "[%d] (ctx %p) Running encoder instance %p => %d\n", | |||
642 | data->level, (void *)data->ctx, | |||
643 | (void *)current_encoder_inst, ok); | |||
644 | } OSSL_TRACE_END(ENCODER)} while(0); | |||
645 | } | |||
646 | ||||
647 | ossl_core_bio_free(cbio); | |||
648 | data->prev_encoder_inst = current_encoder_inst; | |||
649 | } | |||
650 | } | |||
651 | ||||
652 | /* Cleanup and collecting the result */ | |||
653 | ||||
654 | OPENSSL_free(data->running_output)CRYPTO_free(data->running_output, "../deps/openssl/openssl/crypto/encode_decode/encoder_lib.c" , 654); | |||
655 | data->running_output = NULL((void*)0); | |||
656 | ||||
657 | /* | |||
658 | * Steal the output from the BIO_s_mem, if we did allocate one. | |||
659 | * That'll be the data for an object abstraction in the next round. | |||
660 | */ | |||
661 | if (allocated_out != NULL((void*)0)) { | |||
662 | BUF_MEM *buf; | |||
663 | ||||
664 | BIO_get_mem_ptr(allocated_out, &buf)BIO_ctrl(allocated_out,115,0, (char *)(&buf)); | |||
665 | data->running_output = (unsigned char *)buf->data; | |||
666 | data->running_output_length = buf->length; | |||
667 | memset(buf, 0, sizeof(*buf)); | |||
668 | } | |||
669 | ||||
670 | BIO_free(allocated_out); | |||
671 | if (original_data != NULL((void*)0)) | |||
672 | data->ctx->cleanup(data->ctx->construct_data); | |||
673 | return ok; | |||
674 | } |