| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:52:38 +08:00
										 |  |  |  * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |  * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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 <string.h>
 | 
					
						
							|  |  |  | #include <openssl/err.h>
 | 
					
						
							|  |  |  | #include <openssl/lhash.h>
 | 
					
						
							|  |  |  | #include "internal/propertyerr.h"
 | 
					
						
							|  |  |  | #include "internal/property.h"
 | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  | #include "internal/core.h"
 | 
					
						
							| 
									
										
										
										
											2019-09-28 06:45:40 +08:00
										 |  |  | #include "property_local.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  | #include "crypto/context.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Implement a property definition cache. | 
					
						
							|  |  |  |  * These functions assume that they are called under a write lock. | 
					
						
							|  |  |  |  * No attempt is made to clean out the cache, except when it is shut down. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |     const char *prop; | 
					
						
							|  |  |  |     OSSL_PROPERTY_LIST *defn; | 
					
						
							|  |  |  |     char body[1]; | 
					
						
							|  |  |  | } PROPERTY_DEFN_ELEM; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 19:52:27 +08:00
										 |  |  | DEFINE_LHASH_OF_EX(PROPERTY_DEFN_ELEM); | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return OPENSSL_LH_strhash(a->prop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int property_defn_cmp(const PROPERTY_DEFN_ELEM *a, | 
					
						
							|  |  |  |                              const PROPERTY_DEFN_ELEM *b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return strcmp(a->prop, b->prop); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void property_defn_free(PROPERTY_DEFN_ELEM *elem) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ossl_property_free(elem->defn); | 
					
						
							|  |  |  |     OPENSSL_free(elem); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  | void ossl_property_defns_free(void *vproperty_defns) | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |     LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns = vproperty_defns; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (property_defns != NULL) { | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |         lh_PROPERTY_DEFN_ELEM_doall(property_defns, | 
					
						
							|  |  |  |                                     &property_defn_free); | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |         lh_PROPERTY_DEFN_ELEM_free(property_defns); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  | void *ossl_property_defns_new(OSSL_LIB_CTX *ctx) { | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |     return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | OSSL_PROPERTY_LIST *ossl_prop_defn_get(OSSL_LIB_CTX *ctx, const char *prop) | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     PROPERTY_DEFN_ELEM elem, *r; | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |     LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |     property_defns = ossl_lib_ctx_get_data(ctx, | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |                                            OSSL_LIB_CTX_PROPERTY_DEFN_INDEX); | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |     if (!ossl_assert(property_defns != NULL) || !ossl_lib_ctx_read_lock(ctx)) | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     elem.prop = prop; | 
					
						
							|  |  |  |     r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem); | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |     ossl_lib_ctx_unlock(ctx); | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |     if (r == NULL || !ossl_assert(r->defn != NULL)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     return r->defn; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 17:06:57 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |  * Cache the property list for a given property string *pl. | 
					
						
							|  |  |  |  * If an entry already exists in the cache *pl is freed and | 
					
						
							|  |  |  |  * overwritten with the existing entry from the cache. | 
					
						
							| 
									
										
										
										
											2022-06-06 17:06:57 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop, | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |                        OSSL_PROPERTY_LIST **pl) | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     PROPERTY_DEFN_ELEM elem, *old, *p = NULL; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |     LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |     int res = 1; | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |     property_defns = ossl_lib_ctx_get_data(ctx, | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |                                            OSSL_LIB_CTX_PROPERTY_DEFN_INDEX); | 
					
						
							| 
									
										
										
										
											2019-05-01 18:02:43 +08:00
										 |  |  |     if (property_defns == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (prop == NULL) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |     if (!ossl_lib_ctx_write_lock(ctx)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |     elem.prop = prop; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |     if (pl == NULL) { | 
					
						
							|  |  |  |         lh_PROPERTY_DEFN_ELEM_delete(property_defns, &elem); | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |         goto end; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |     /* check if property definition is in the cache already */ | 
					
						
							|  |  |  |     if ((p = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem)) != NULL) { | 
					
						
							|  |  |  |         ossl_property_free(*pl); | 
					
						
							|  |  |  |         *pl = p->defn; | 
					
						
							|  |  |  |         goto end; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |     len = strlen(prop); | 
					
						
							|  |  |  |     p = OPENSSL_malloc(sizeof(*p) + len); | 
					
						
							|  |  |  |     if (p != NULL) { | 
					
						
							|  |  |  |         p->prop = p->body; | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |         p->defn = *pl; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |         memcpy(p->body, prop, len + 1); | 
					
						
							|  |  |  |         old = lh_PROPERTY_DEFN_ELEM_insert(property_defns, p); | 
					
						
							| 
									
										
										
										
											2022-11-25 01:48:10 +08:00
										 |  |  |         if (!ossl_assert(old == NULL)) | 
					
						
							|  |  |  |             /* This should not happen. An existing entry is handled above. */ | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |             goto end; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |         if (!lh_PROPERTY_DEFN_ELEM_error(property_defns)) | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |             goto end; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     OPENSSL_free(p); | 
					
						
							| 
									
										
										
										
											2021-04-07 09:32:59 +08:00
										 |  |  |     res = 0; | 
					
						
							|  |  |  |  end: | 
					
						
							|  |  |  |     ossl_lib_ctx_unlock(ctx); | 
					
						
							|  |  |  |     return res; | 
					
						
							| 
									
										
										
										
											2018-11-16 09:44:30 +08:00
										 |  |  | } |