| 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 | } |