Skip to content

Commit f480a73

Browse files
igus68t8m
authored andcommitted
Added finalized flag to the OSSL_ENCODER/DECODER_CTX structures
After this flag is set, the generic OSSL_ENCODER/DECODER_CTX_set_*() functions shouldn't be called anymore, so they return error in this case. Fixes #28249 Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from #29120)
1 parent de89ca9 commit f480a73

14 files changed

Lines changed: 274 additions & 6 deletions

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ OpenSSL 4.0
4646

4747
*Ryan Hooper*
4848

49+
* Added `OSSL_[EN|DE]CODER_CTX_[set|get]_finalized()` functions.
50+
`OSSL_[EN|DE]CODER_CTX_set_*()` and `OSSL_[EN|DE]CODER_CTX_add_*()`
51+
functions return 0 if the context is already finalised.
52+
53+
*Igor Ustinov*
54+
4955
OpenSSL 3.6
5056
-----------
5157

crypto/encode_decode/decoder_lib.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ int OSSL_DECODER_CTX_set_selection(OSSL_DECODER_CTX *ctx, int selection)
170170
return 0;
171171
}
172172

173+
if (ctx->finalized != 0) {
174+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
175+
return 0;
176+
}
177+
173178
/*
174179
* 0 is a valid selection, and means that the caller leaves
175180
* it to code to discover what the selection is.
@@ -186,6 +191,11 @@ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx,
186191
return 0;
187192
}
188193

194+
if (ctx->finalized != 0) {
195+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
196+
return 0;
197+
}
198+
189199
/*
190200
* NULL is a valid starting input type, and means that the caller leaves
191201
* it to code to discover what the starting input type is.
@@ -202,6 +212,11 @@ int OSSL_DECODER_CTX_set_input_structure(OSSL_DECODER_CTX *ctx,
202212
return 0;
203213
}
204214

215+
if (ctx->finalized != 0) {
216+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
217+
return 0;
218+
}
219+
205220
/*
206221
* NULL is a valid starting input structure, and means that the caller
207222
* leaves it to code to discover what the starting input structure is.
@@ -388,6 +403,11 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder)
388403
return 0;
389404
}
390405

406+
if (ctx->finalized != 0) {
407+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
408+
return 0;
409+
}
410+
391411
prov = OSSL_DECODER_get0_provider(decoder);
392412
provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
393413

@@ -582,6 +602,11 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx,
582602
return 0;
583603
}
584604

605+
if (ctx->finalized != 0) {
606+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
607+
return 0;
608+
}
609+
585610
/*
586611
* If there is no stack of OSSL_DECODER_INSTANCE, we have nothing
587612
* more to add. That's fine.
@@ -684,6 +709,12 @@ int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx,
684709
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
685710
return 0;
686711
}
712+
713+
if (ctx->finalized != 0) {
714+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
715+
return 0;
716+
}
717+
687718
ctx->construct = construct;
688719
return 1;
689720
}
@@ -695,6 +726,12 @@ int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx,
695726
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
696727
return 0;
697728
}
729+
730+
if (ctx->finalized != 0) {
731+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
732+
return 0;
733+
}
734+
698735
ctx->construct_data = construct_data;
699736
return 1;
700737
}
@@ -706,10 +743,35 @@ int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx,
706743
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
707744
return 0;
708745
}
746+
747+
if (ctx->finalized != 0) {
748+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
749+
return 0;
750+
}
751+
709752
ctx->cleanup = cleanup;
710753
return 1;
711754
}
712755

756+
int OSSL_DECODER_CTX_set_finalized(OSSL_DECODER_CTX *ctx)
757+
{
758+
if (ctx == NULL) {
759+
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER);
760+
return 0;
761+
}
762+
763+
ctx->finalized = 1;
764+
return 1;
765+
}
766+
767+
int OSSL_DECODER_CTX_get_finalized(OSSL_DECODER_CTX *ctx)
768+
{
769+
if (ctx == NULL)
770+
return 0;
771+
772+
return ctx->finalized;
773+
}
774+
713775
OSSL_DECODER_CONSTRUCT *
714776
OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx)
715777
{

crypto/encode_decode/decoder_pkey.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@ OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey,
877877
&& OSSL_DECODER_CTX_set_selection(ctx, selection)
878878
&& ossl_decoder_ctx_setup_for_pkey(ctx, keytype, libctx, propquery)
879879
&& OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)
880+
&& OSSL_DECODER_CTX_set_finalized(ctx)
880881
&& (propquery == NULL
881882
|| OSSL_DECODER_CTX_set_params(ctx, decoder_params))) {
882883
OSSL_TRACE_BEGIN(DECODER) {

crypto/encode_decode/encoder_lib.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ int OSSL_ENCODER_CTX_set_selection(OSSL_ENCODER_CTX *ctx, int selection)
174174
return 0;
175175
}
176176

177+
if (ctx->finalized != 0) {
178+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
179+
return 0;
180+
}
181+
177182
if (!ossl_assert(selection != 0)) {
178183
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT);
179184
return 0;
@@ -191,6 +196,11 @@ int OSSL_ENCODER_CTX_set_output_type(OSSL_ENCODER_CTX *ctx,
191196
return 0;
192197
}
193198

199+
if (ctx->finalized != 0) {
200+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
201+
return 0;
202+
}
203+
194204
ctx->output_type = output_type;
195205
return 1;
196206
}
@@ -203,6 +213,11 @@ int OSSL_ENCODER_CTX_set_output_structure(OSSL_ENCODER_CTX *ctx,
203213
return 0;
204214
}
205215

216+
if (ctx->finalized != 0) {
217+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
218+
return 0;
219+
}
220+
206221
ctx->output_structure = output_structure;
207222
return 1;
208223
}
@@ -315,6 +330,11 @@ int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder)
315330
return 0;
316331
}
317332

333+
if (ctx->finalized != 0) {
334+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
335+
return 0;
336+
}
337+
318338
prov = OSSL_ENCODER_get0_provider(encoder);
319339
provctx = OSSL_PROVIDER_get0_provider_ctx(prov);
320340

@@ -339,6 +359,16 @@ int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder)
339359
int OSSL_ENCODER_CTX_add_extra(OSSL_ENCODER_CTX *ctx,
340360
OSSL_LIB_CTX *libctx, const char *propq)
341361
{
362+
if (ctx == NULL) {
363+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
364+
return 0;
365+
}
366+
367+
if (ctx->finalized != 0) {
368+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
369+
return 0;
370+
}
371+
342372
return 1;
343373
}
344374

@@ -356,6 +386,12 @@ int OSSL_ENCODER_CTX_set_construct(OSSL_ENCODER_CTX *ctx,
356386
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
357387
return 0;
358388
}
389+
390+
if (ctx->finalized != 0) {
391+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
392+
return 0;
393+
}
394+
359395
ctx->construct = construct;
360396
return 1;
361397
}
@@ -367,6 +403,12 @@ int OSSL_ENCODER_CTX_set_construct_data(OSSL_ENCODER_CTX *ctx,
367403
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
368404
return 0;
369405
}
406+
407+
if (ctx->finalized != 0) {
408+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
409+
return 0;
410+
}
411+
370412
ctx->construct_data = construct_data;
371413
return 1;
372414
}
@@ -378,10 +420,35 @@ int OSSL_ENCODER_CTX_set_cleanup(OSSL_ENCODER_CTX *ctx,
378420
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
379421
return 0;
380422
}
423+
424+
if (ctx->finalized != 0) {
425+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
426+
return 0;
427+
}
428+
381429
ctx->cleanup = cleanup;
382430
return 1;
383431
}
384432

433+
int OSSL_ENCODER_CTX_set_finalized(OSSL_ENCODER_CTX *ctx)
434+
{
435+
if (ctx == NULL) {
436+
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER);
437+
return 0;
438+
}
439+
440+
ctx->finalized = 1;
441+
return 1;
442+
}
443+
444+
int OSSL_ENCODER_CTX_get_finalized(OSSL_ENCODER_CTX *ctx)
445+
{
446+
if (ctx == NULL)
447+
return 0;
448+
449+
return ctx->finalized;
450+
}
451+
385452
OSSL_ENCODER *
386453
OSSL_ENCODER_INSTANCE_get_encoder(OSSL_ENCODER_INSTANCE *encoder_inst)
387454
{

crypto/encode_decode/encoder_local.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ struct ossl_encoder_ctx_st {
101101

102102
/* For any function that needs a passphrase reader */
103103
struct ossl_passphrase_data_st pwdata;
104+
105+
/* Flag that the structure is ready for use */
106+
int finalized;
104107
};
105108

106109
struct ossl_decoder_instance_st {
@@ -162,6 +165,9 @@ struct ossl_decoder_ctx_st {
162165

163166
/* Signal that further processing should not continue. */
164167
int harderr;
168+
169+
/* Flag that the structure is ready for use */
170+
int finalized;
165171
};
166172

167173
const OSSL_PROPERTY_LIST *

crypto/encode_decode/encoder_pkey.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_for_pkey(const EVP_PKEY *pkey,
388388
|| OSSL_ENCODER_CTX_set_output_structure(ctx, output_struct))
389389
&& OSSL_ENCODER_CTX_set_selection(ctx, selection)
390390
&& ossl_encoder_ctx_setup_for_pkey(ctx, pkey, selection, propquery)
391-
&& OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) {
391+
&& OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)
392+
&& OSSL_ENCODER_CTX_set_finalized(ctx)) {
392393
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
393394
int save_parameters = pkey->save_parameters;
394395

doc/man3/OSSL_DECODER_CTX.pod

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ OSSL_DECODER_CLEANUP,
1919
OSSL_DECODER_CTX_set_construct,
2020
OSSL_DECODER_CTX_set_construct_data,
2121
OSSL_DECODER_CTX_set_cleanup,
22+
OSSL_DECODER_CTX_set_finalized,
2223
OSSL_DECODER_CTX_get_construct,
2324
OSSL_DECODER_CTX_get_construct_data,
2425
OSSL_DECODER_CTX_get_cleanup,
26+
OSSL_DECODER_CTX_get_finalized,
2527
OSSL_DECODER_export,
2628
OSSL_DECODER_INSTANCE_get_decoder,
2729
OSSL_DECODER_INSTANCE_get_decoder_ctx,
@@ -77,6 +79,9 @@ OSSL_DECODER_INSTANCE_get_input_structure
7779
void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx);
7880
OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx);
7981

82+
int OSSL_DECODER_CTX_set_finalized(OSSL_DECODER_CTX *ctx);
83+
int OSSL_DECODER_CTX_get_finalized(OSSL_DECODER_CTX *ctx);
84+
8085
int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst,
8186
void *reference, size_t reference_sz,
8287
OSSL_CALLBACK *export_cb, void *export_cbarg);
@@ -135,6 +140,8 @@ OSSL_DECODER_CTX_add_extra() finds decoders that generate input for already
135140
added decoders, and adds them as well. This is used to build decoder
136141
chains.
137142

143+
OSSL_DECODER_CTX_set_selection() sets what the input is expected to contain.
144+
138145
OSSL_DECODER_CTX_set_input_type() sets the starting input type. This limits
139146
the decoder chains to be considered, as explained in the general description
140147
above.
@@ -160,6 +167,15 @@ OSSL_DECODER_CTX_get_cleanup() return the values that have been set by
160167
OSSL_DECODER_CTX_set_construct(), OSSL_DECODER_CTX_set_construct_data() and
161168
OSSL_DECODER_CTX_set_cleanup() respectively.
162169

170+
OSSL_DECODER_CTX_set_finalized() finalises the context. Functions
171+
OSSL_DECODER_CTX_set_selection(), OSSL_DECODER_CTX_set_output_type(),
172+
OSSL_DECODER_CTX_set_output_structure(), OSSL_DECODER_CTX_add_encoder(),
173+
OSSL_DECODER_CTX_add_extra(), OSSL_DECODER_CTX_set_construct(),
174+
OSSL_DECODER_CTX_set_construct_data() and OSSL_DECODER_CTX_set_cleanup()
175+
can't be used after the context is finalised.
176+
177+
OSSL_DECODER_CTX_get_finalized() indicates if the context was finalised.
178+
163179
OSSL_DECODER_export() is a fallback function for constructors that cannot
164180
use the data they get directly for diverse reasons. It takes the same
165181
decode instance I<decoder_inst> that the constructor got and an object
@@ -221,14 +237,20 @@ OSSL_DECODER_CTX_set_params() returns 1 if all recognised parameters were
221237
valid, or 0 if one of them was invalid or caused some other failure in the
222238
implementation.
223239

240+
OSSL_DECODER_CTX_set_selection(), OSSL_DECODER_CTX_set_input_type(),
241+
OSSL_DECODER_CTX_set_input_structure(),
224242
OSSL_DECODER_CTX_add_decoder(), OSSL_DECODER_CTX_add_extra(),
225-
OSSL_DECODER_CTX_set_construct(), OSSL_DECODER_CTX_set_construct_data() and
226-
OSSL_DECODER_CTX_set_cleanup() return 1 on success, or 0 on failure.
243+
OSSL_DECODER_CTX_set_construct(), OSSL_DECODER_CTX_set_construct_data(),
244+
OSSL_DECODER_CTX_set_cleanup() and OSSL_DECODER_CTX_set_finalized()
245+
return 1 on success, or 0 on failure.
227246

228247
OSSL_DECODER_CTX_get_construct(), OSSL_DECODER_CTX_get_construct_data() and
229248
OSSL_DECODER_CTX_get_cleanup() return the current pointers to the
230249
constructor, the constructor data and the cleanup functions, respectively.
231250

251+
OSSL_DECODER_CTX_get_finalized() returns 1 if I<ctx> was finalised,
252+
0 otherwise. It also returns 0 if I<ctx> is NULL.
253+
232254
OSSL_DECODER_CTX_num_decoders() returns the current number of decoders. It
233255
returns 0 if I<ctx> is NULL.
234256

@@ -248,6 +270,9 @@ L<provider(7)>, L<OSSL_DECODER(3)>, L<OSSL_DECODER_from_bio(3)>
248270

249271
The functions described here were added in OpenSSL 3.0.
250272

273+
OSSL_DECODER_CTX_set_finalized() and OSSL_DECODER_CTX_get_finalized()
274+
were added in OpenSSL 4.0.
275+
251276
=head1 COPYRIGHT
252277

253278
Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.

doc/man3/OSSL_DECODER_CTX_new_for_pkey.pod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ zero). This helps the caller to distinguish between an error when creating
7171
the B<OSSL_ENCODER_CTX> and missing encoder implementation, and allows it to
7272
act accordingly.
7373

74+
Note that OSSL_DECODER_CTX_new_for_pkey() finalises the OSSL_DECODER_CTX;
75+
after that the B<OSSL_DECODER_CTX_set_*()> and B<OSSL_DECODER_CTX_add_*()>
76+
functions described in L<OSSL_DECODER_CTX(3)> shouldn't be called.
77+
7478
OSSL_DECODER_CTX_set_passphrase() gives the implementation a pass phrase to
7579
use when decrypting the encoded private key. Alternatively, a pass phrase
7680
callback may be specified with the following functions.

0 commit comments

Comments
 (0)