| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-03-15 21:52:58 +08:00
										 |  |  |  * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <openssl/err.h>
 | 
					
						
							|  |  |  | #include <openssl/ui.h>
 | 
					
						
							|  |  |  | #include <openssl/params.h>
 | 
					
						
							|  |  |  | #include <openssl/encoder.h>
 | 
					
						
							|  |  |  | #include <openssl/core_names.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  | #include <openssl/provider.h>
 | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | #include <openssl/safestack.h>
 | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  | #include <openssl/trace.h>
 | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | #include "internal/provider.h"
 | 
					
						
							|  |  |  | #include "internal/property.h"
 | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  | #include "internal/namemap.h"
 | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | #include "crypto/evp.h"
 | 
					
						
							|  |  |  | #include "encoder_local.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | DEFINE_STACK_OF(OSSL_ENCODER) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx, | 
					
						
							|  |  |  |                                 const char *cipher_name, | 
					
						
							|  |  |  |                                 const char *propquery) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     params[0] = | 
					
						
							|  |  |  |         OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_CIPHER, | 
					
						
							|  |  |  |                                          (void *)cipher_name, 0); | 
					
						
							|  |  |  |     params[1] = | 
					
						
							|  |  |  |         OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, | 
					
						
							|  |  |  |                                          (void *)propquery, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return OSSL_ENCODER_CTX_set_params(ctx, params); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx, | 
					
						
							|  |  |  |                                     const unsigned char *kstr, | 
					
						
							|  |  |  |                                     size_t klen) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-07 18:25:17 +08:00
										 |  |  |     return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx, | 
					
						
							|  |  |  |                                        const UI_METHOD *ui_method, | 
					
						
							|  |  |  |                                        void *ui_data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-02 18:14:19 +08:00
										 |  |  |     return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | int OSSL_ENCODER_CTX_set_pem_password_cb(OSSL_ENCODER_CTX *ctx, | 
					
						
							|  |  |  |                                          pem_password_cb *cb, void *cbarg) | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-08-02 18:14:19 +08:00
										 |  |  |     return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx, | 
					
						
							|  |  |  |                                        OSSL_PASSPHRASE_CALLBACK *cb, | 
					
						
							|  |  |  |                                        void *cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  |  * Support for OSSL_ENCODER_CTX_new_for_type: | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |  * finding a suitable encoder | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | struct collected_encoder_st { | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |     STACK_OF(OPENSSL_CSTRING) *names; | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |     int *id_names; | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |     const char *output_structure; | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     const char *output_type; | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-19 00:28:25 +08:00
										 |  |  |     const OSSL_PROVIDER *keymgmt_prov; | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |     OSSL_ENCODER_CTX *ctx; | 
					
						
							| 
									
										
										
										
											2021-06-28 11:37:22 +08:00
										 |  |  |     unsigned int flag_find_same_provider:1; | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     int error_occurred; | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void collect_encoder(OSSL_ENCODER *encoder, void *arg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct collected_encoder_st *data = arg; | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |     const OSSL_PROVIDER *prov; | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     if (data->error_occurred) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     data->error_occurred = 1;     /* Assume the worst */ | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |     prov = OSSL_ENCODER_get0_provider(encoder); | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * collect_encoder() is called in two passes, one where the encoders | 
					
						
							|  |  |  |      * from the same provider as the keymgmt are looked up, and one where | 
					
						
							|  |  |  |      * the other encoders are looked up.  |data->flag_find_same_provider| | 
					
						
							|  |  |  |      * tells us which pass we're in. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if ((data->keymgmt_prov == prov) == data->flag_find_same_provider) { | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |         void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov); | 
					
						
							| 
									
										
										
										
											2022-10-14 09:53:02 +08:00
										 |  |  |         int i, end_i = sk_OPENSSL_CSTRING_num(data->names); | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |         int match; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (i = 0; i < end_i; i++) { | 
					
						
							|  |  |  |             if (data->flag_find_same_provider) | 
					
						
							|  |  |  |                 match = (data->id_names[i] == encoder->base.id); | 
					
						
							|  |  |  |             else | 
					
						
							| 
									
										
										
										
											2022-10-14 09:53:02 +08:00
										 |  |  |                 match = OSSL_ENCODER_is_a(encoder, | 
					
						
							|  |  |  |                                           sk_OPENSSL_CSTRING_value(data->names, i)); | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |             if (!match | 
					
						
							|  |  |  |                 || (encoder->does_selection != NULL | 
					
						
							|  |  |  |                     && !encoder->does_selection(provctx, data->ctx->selection)) | 
					
						
							|  |  |  |                 || (data->keymgmt_prov != prov | 
					
						
							|  |  |  |                     && encoder->import_object == NULL)) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             /* Only add each encoder implementation once */ | 
					
						
							|  |  |  |             if (OSSL_ENCODER_CTX_add_encoder(data->ctx, encoder)) | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     data->error_occurred = 0;         /* All is good now */ | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct collected_names_st { | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |     STACK_OF(OPENSSL_CSTRING) *names; | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     unsigned int error_occurred:1; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | static void collect_name(const char *name, void *arg) | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     struct collected_names_st *data = arg; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     if (data->error_occurred) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     data->error_occurred = 1;         /* Assume the worst */ | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     if (sk_OPENSSL_CSTRING_push(data->names, name) <= 0) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |     data->error_occurred = 0;         /* All is good now */ | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Support for OSSL_ENCODER_to_bio: | 
					
						
							|  |  |  |  * writing callback for the OSSL_PARAM (the implementation doesn't have | 
					
						
							|  |  |  |  * intimate knowledge of the provider side object) | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | struct construct_data_st { | 
					
						
							|  |  |  |     const EVP_PKEY *pk; | 
					
						
							|  |  |  |     int selection; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     OSSL_ENCODER_INSTANCE *encoder_inst; | 
					
						
							|  |  |  |     const void *obj; | 
					
						
							|  |  |  |     void *constructed_obj; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | static int encoder_import_cb(const OSSL_PARAM params[], void *arg) | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     struct construct_data_st *construct_data = arg; | 
					
						
							|  |  |  |     OSSL_ENCODER_INSTANCE *encoder_inst = construct_data->encoder_inst; | 
					
						
							|  |  |  |     OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); | 
					
						
							|  |  |  |     void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     construct_data->constructed_obj = | 
					
						
							|  |  |  |         encoder->import_object(encoderctx, construct_data->selection, params); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     return (construct_data->constructed_obj != NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const void * | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  | encoder_construct_pkey(OSSL_ENCODER_INSTANCE *encoder_inst, void *arg) | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     struct construct_data_st *data = arg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (data->obj == NULL) { | 
					
						
							|  |  |  |         OSSL_ENCODER *encoder = | 
					
						
							|  |  |  |             OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); | 
					
						
							|  |  |  |         const EVP_PKEY *pk = data->pk; | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |         const OSSL_PROVIDER *k_prov = EVP_KEYMGMT_get0_provider(pk->keymgmt); | 
					
						
							|  |  |  |         const OSSL_PROVIDER *e_prov = OSSL_ENCODER_get0_provider(encoder); | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (k_prov != e_prov) { | 
					
						
							|  |  |  |             data->encoder_inst = encoder_inst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, data->selection, | 
					
						
							|  |  |  |                                     &encoder_import_cb, data)) | 
					
						
							|  |  |  |                 return NULL; | 
					
						
							|  |  |  |             data->obj = data->constructed_obj; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             data->obj = pk->keydata; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     return data->obj; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  | static void encoder_destruct_pkey(void *arg) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     struct construct_data_st *data = arg; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     if (data->encoder_inst != NULL) { | 
					
						
							|  |  |  |         OSSL_ENCODER *encoder = | 
					
						
							|  |  |  |             OSSL_ENCODER_INSTANCE_get_encoder(data->encoder_inst); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         encoder->free_object(data->constructed_obj); | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     data->constructed_obj = NULL; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  |  * OSSL_ENCODER_CTX_new_for_pkey() returns a ctx with no encoder if | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |  * it couldn't find a suitable encoder.  This allows a caller to detect if | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |  * a suitable encoder was found, with OSSL_ENCODER_CTX_get_num_encoder(), | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |  * and to use fallback methods if the result is NULL. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  | static int ossl_encoder_ctx_setup_for_pkey(OSSL_ENCODER_CTX *ctx, | 
					
						
							|  |  |  |                                            const EVP_PKEY *pkey, | 
					
						
							|  |  |  |                                            int selection, | 
					
						
							|  |  |  |                                            const char *propquery) | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     struct construct_data_st *data = NULL; | 
					
						
							| 
									
										
										
										
											2021-04-19 00:28:25 +08:00
										 |  |  |     const OSSL_PROVIDER *prov = NULL; | 
					
						
							| 
									
										
										
										
											2020-11-27 14:59:02 +08:00
										 |  |  |     OSSL_LIB_CTX *libctx = NULL; | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |     int ok = 0, i, end; | 
					
						
							|  |  |  |     OSSL_NAMEMAP *namemap; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     if (!ossl_assert(ctx != NULL) || !ossl_assert(pkey != NULL)) { | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |         ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 14:59:02 +08:00
										 |  |  |     if (evp_pkey_is_provided(pkey)) { | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |         prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt); | 
					
						
							| 
									
										
										
										
											2020-11-27 14:59:02 +08:00
										 |  |  |         libctx = ossl_provider_libctx(prov); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     if (pkey->keymgmt != NULL) { | 
					
						
							|  |  |  |         struct collected_encoder_st encoder_data; | 
					
						
							|  |  |  |         struct collected_names_st keymgmt_data; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |         /*
 | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |          * Select the first encoder implementations in two steps. | 
					
						
							|  |  |  |          * First, collect the keymgmt names, then the encoders that match. | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |          */ | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         keymgmt_data.names = sk_OPENSSL_CSTRING_new_null(); | 
					
						
							| 
									
										
										
										
											2022-03-08 19:48:54 +08:00
										 |  |  |         if (keymgmt_data.names == NULL) { | 
					
						
							|  |  |  |             ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |         keymgmt_data.error_occurred = 0; | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         EVP_KEYMGMT_names_do_all(pkey->keymgmt, collect_name, &keymgmt_data); | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |         if (keymgmt_data.error_occurred) { | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |             sk_OPENSSL_CSTRING_free(keymgmt_data.names); | 
					
						
							|  |  |  |             goto err; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |         encoder_data.names = keymgmt_data.names; | 
					
						
							|  |  |  |         encoder_data.output_type = ctx->output_type; | 
					
						
							|  |  |  |         encoder_data.output_structure = ctx->output_structure; | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |         encoder_data.error_occurred = 0; | 
					
						
							| 
									
										
										
										
											2021-04-19 00:28:25 +08:00
										 |  |  |         encoder_data.keymgmt_prov = prov; | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |         encoder_data.ctx = ctx; | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |         encoder_data.id_names = NULL; | 
					
						
							| 
									
										
										
										
											2021-06-28 11:37:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * collect_encoder() is called many times, and for every call it converts all encoder_data.names | 
					
						
							|  |  |  |          * into namemap ids if it calls OSSL_ENCODER_is_a(). We cache the ids here instead, | 
					
						
							|  |  |  |          * and can use them for encoders with the same provider as the keymgmt. | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         namemap = ossl_namemap_stored(libctx); | 
					
						
							|  |  |  |         end = sk_OPENSSL_CSTRING_num(encoder_data.names); | 
					
						
							|  |  |  |         if (end > 0) { | 
					
						
							|  |  |  |             encoder_data.id_names = OPENSSL_malloc(end * sizeof(int)); | 
					
						
							|  |  |  |             if (encoder_data.id_names == NULL) | 
					
						
							|  |  |  |                 goto err; | 
					
						
							|  |  |  |             for (i = 0; i < end; ++i) { | 
					
						
							|  |  |  |                 const char *name = sk_OPENSSL_CSTRING_value(keymgmt_data.names, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 encoder_data.id_names[i] = ossl_namemap_name2num(namemap, name); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-28 11:37:22 +08:00
										 |  |  |         /*
 | 
					
						
							|  |  |  |          * Place the encoders with the a different provider as the keymgmt | 
					
						
							|  |  |  |          * last (the chain is processed in reverse order) | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         encoder_data.flag_find_same_provider = 0; | 
					
						
							|  |  |  |         OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Place the encoders with the same provider as the keymgmt first | 
					
						
							|  |  |  |          * (the chain is processed in reverse order) | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         encoder_data.flag_find_same_provider = 1; | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |         OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data); | 
					
						
							| 
									
										
										
										
											2021-06-28 11:37:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 07:57:51 +08:00
										 |  |  |         OPENSSL_free(encoder_data.id_names); | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         sk_OPENSSL_CSTRING_free(keymgmt_data.names); | 
					
						
							| 
									
										
										
										
											2021-03-03 01:15:32 +08:00
										 |  |  |         if (encoder_data.error_occurred) { | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |             ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 11:05:16 +08:00
										 |  |  |     if (data != NULL && OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) { | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  |         if (!OSSL_ENCODER_CTX_set_construct(ctx, encoder_construct_pkey) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |             || !OSSL_ENCODER_CTX_set_construct_data(ctx, data) | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  |             || !OSSL_ENCODER_CTX_set_cleanup(ctx, encoder_destruct_pkey)) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |             goto err; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         data->pk = pkey; | 
					
						
							|  |  |  |         data->selection = selection; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         data = NULL;             /* Avoid it being freed */ | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     ok = 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     if (data != NULL) { | 
					
						
							|  |  |  |         OSSL_ENCODER_CTX_set_construct_data(ctx, NULL); | 
					
						
							|  |  |  |         OPENSSL_free(data); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ok; | 
					
						
							| 
									
										
										
										
											2020-08-17 03:25:08 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  | OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_for_pkey(const EVP_PKEY *pkey, | 
					
						
							|  |  |  |                                                 int selection, | 
					
						
							|  |  |  |                                                 const char *output_type, | 
					
						
							|  |  |  |                                                 const char *output_struct, | 
					
						
							|  |  |  |                                                 const char *propquery) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     OSSL_ENCODER_CTX *ctx = NULL; | 
					
						
							| 
									
										
										
										
											2020-11-27 14:59:02 +08:00
										 |  |  |     OSSL_LIB_CTX *libctx = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (pkey == NULL) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!evp_pkey_is_assigned(pkey)) { | 
					
						
							|  |  |  |         ERR_raise_data(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT, | 
					
						
							|  |  |  |                        "The passed EVP_PKEY must be assigned a key"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((ctx = OSSL_ENCODER_CTX_new()) == NULL) { | 
					
						
							|  |  |  |         ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 14:59:02 +08:00
										 |  |  |     if (evp_pkey_is_provided(pkey)) { | 
					
						
							| 
									
										
										
											
												Rename all getters to use get/get0 in name
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes #15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
											
										 
											2021-05-21 22:58:08 +08:00
										 |  |  |         const OSSL_PROVIDER *prov = EVP_KEYMGMT_get0_provider(pkey->keymgmt); | 
					
						
							| 
									
										
										
										
											2020-11-27 14:59:02 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         libctx = ossl_provider_libctx(prov); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  |     OSSL_TRACE_BEGIN(ENCODER) { | 
					
						
							|  |  |  |         BIO_printf(trc_out, | 
					
						
							|  |  |  |                    "(ctx %p) Looking for %s encoders with selection %d\n", | 
					
						
							| 
									
										
										
										
											2021-04-14 18:42:30 +08:00
										 |  |  |                    (void *)ctx, EVP_PKEY_get0_type_name(pkey), selection); | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  |         BIO_printf(trc_out, "    output type: %s, output structure: %s\n", | 
					
						
							|  |  |  |                    output_type, output_struct); | 
					
						
							|  |  |  |     } OSSL_TRACE_END(ENCODER); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |     if (OSSL_ENCODER_CTX_set_output_type(ctx, output_type) | 
					
						
							| 
									
										
										
										
											2020-10-17 14:23:43 +08:00
										 |  |  |         && (output_struct == NULL | 
					
						
							|  |  |  |             || OSSL_ENCODER_CTX_set_output_structure(ctx, output_struct)) | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         && OSSL_ENCODER_CTX_set_selection(ctx, selection) | 
					
						
							| 
									
										
										
										
											2021-02-11 23:57:37 +08:00
										 |  |  |         && ossl_encoder_ctx_setup_for_pkey(ctx, pkey, selection, propquery) | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  |         && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) { | 
					
						
							| 
									
										
										
										
											2021-03-30 23:41:03 +08:00
										 |  |  |         OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | 
					
						
							|  |  |  |         int save_parameters = pkey->save_parameters; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         params[0] = OSSL_PARAM_construct_int(OSSL_ENCODER_PARAM_SAVE_PARAMETERS, | 
					
						
							|  |  |  |                                              &save_parameters); | 
					
						
							|  |  |  |         /* ignoring error as this is only auxiliary parameter */ | 
					
						
							|  |  |  |         (void)OSSL_ENCODER_CTX_set_params(ctx, params); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  |         OSSL_TRACE_BEGIN(ENCODER) { | 
					
						
							|  |  |  |             BIO_printf(trc_out, "(ctx %p) Got %d encoders\n", | 
					
						
							|  |  |  |                        (void *)ctx, OSSL_ENCODER_CTX_get_num_encoders(ctx)); | 
					
						
							|  |  |  |         } OSSL_TRACE_END(ENCODER); | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  |         return ctx; | 
					
						
							| 
									
										
										
										
											2020-10-28 17:14:53 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-14 15:20:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     OSSL_ENCODER_CTX_free(ctx); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } |