| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | =pod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 NAME | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | openssl_ctx_get_data, openssl_ctx_run_once, openssl_ctx_onfree | 
					
						
							|  |  |  | - internal OPENSSL_CTX routines | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 SYNOPSIS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  #include <openssl/ossl_typ.h> | 
					
						
							|  |  |  |  #include "internal/cryptlib.h" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  typedef struct openssl_ctx_method { | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  |      void *(*new_func)(OPENSSL_CTX *ctx); | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  |      void (*free_func)(void *); | 
					
						
							|  |  |  |  } OPENSSL_CTX_METHOD; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  |  void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index, | 
					
						
							|  |  |  |                             const OPENSSL_CTX_METHOD *meth); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx, | 
					
						
							|  |  |  |                           openssl_ctx_run_once_fn run_once_fn); | 
					
						
							|  |  |  |  int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn); | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 DESCRIPTION | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Internally, the OpenSSL library context C<OPENSSL_CTX> is implemented | 
					
						
							|  |  |  | as a C<CRYPTO_EX_DATA>, which allows data from diverse parts of the | 
					
						
							|  |  |  | library to be added and removed dynamically. | 
					
						
							|  |  |  | Each such data item must have a corresponding CRYPTO_EX_DATA index | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | associated with it. Unlike normal CRYPTO_EX_DATA objects we use static indexes | 
					
						
							| 
									
										
										
										
											2019-07-02 16:04:04 +08:00
										 |  |  | to identify data items. These are mapped transparently to CRYPTO_EX_DATA dynamic | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | indexes internally to the implementation. | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | See the example further down to see how that's done. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | openssl_ctx_get_data() is used to retrieve a pointer to the data in | 
					
						
							|  |  |  | the library context C<ctx> associated with the given C<index>. An | 
					
						
							|  |  |  | OPENSSL_CTX_METHOD must be defined and given in the C<meth> parameter. The index | 
					
						
							|  |  |  | for it should be defined in cryptlib.h. The functions through the method are | 
					
						
							|  |  |  | used to create or free items that are stored at that index whenever a library | 
					
						
							|  |  |  | context is created or freed, meaning that the code that use a data item of that | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | index doesn't have to worry about that, just use the data available. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Deallocation of an index happens automatically when the library | 
					
						
							|  |  |  | context is freed. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | openssl_ctx_run_once is used to run some initialisation routine C<run_once_fn> | 
					
						
							|  |  |  | exactly once per library context C<ctx> object. Each initialisation routine | 
					
						
							|  |  |  | should be allocate a unique run once index in cryptlib.h. | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | Any resources allocated via a run once initialisation routine can be cleaned up | 
					
						
							|  |  |  | using openssl_ctx_onfree. This associates an "on free" routine C<onfreefn> with | 
					
						
							|  |  |  | the library context C<ctx>. When C<ctx> is freed all associated "on free" | 
					
						
							|  |  |  | routines are called. | 
					
						
							| 
									
										
										
										
											2019-02-26 13:11:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | =head1 RETURN VALUES | 
					
						
							| 
									
										
										
										
											2019-02-26 13:11:10 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | openssl_ctx_get_data() returns a pointer on success, or C<NULL> on | 
					
						
							|  |  |  | failure. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | =head1 EXAMPLES | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head2 Initialization | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For a type C<FOO> that should end up in the OpenSSL library context, a | 
					
						
							|  |  |  | small bit of initialization is needed, i.e. to associate a constructor | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | and a destructor to an index. | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  typedef struct foo_st { | 
					
						
							|  |  |  |      int i; | 
					
						
							|  |  |  |      void *data; | 
					
						
							|  |  |  |  } FOO; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  |  static void *foo_new(OPENSSL_CTX *ctx) | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  |  { | 
					
						
							|  |  |  |      FOO *ptr = OPENSSL_zalloc(sizeof(*foo)); | 
					
						
							|  |  |  |      if (ptr != NULL) | 
					
						
							|  |  |  |          ptr->i = 42; | 
					
						
							|  |  |  |      return ptr; | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  |  static void foo_free(void *ptr) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |      OPENSSL_free(ptr); | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  /* | 
					
						
							|  |  |  |   * Include a reference to this in the methods table in context.c  | 
					
						
							|  |  |  |   * OPENSSL_CTX_FOO_INDEX should be added to internal/cryptlib.h | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  |  const OPENSSL_CTX_METHOD foo_method = { | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  |      foo_new, | 
					
						
							|  |  |  |      foo_free | 
					
						
							|  |  |  |  }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head2 Usage | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To get and use the data stored in the library context, simply do this: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  /* | 
					
						
							|  |  |  |   * ctx is received from a caller, | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2019-05-02 21:32:44 +08:00
										 |  |  |  FOO *data = openssl_ctx_get_data(ctx, OPENSSL_CTX_FOO_INDEX, &foo_method); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head2 Run Once | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  void foo_cleanup(OPENSSL_CTX *ctx) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |      /* Free foo resources associated with ctx */ | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  static openssl_ctx_run_once_fn do_foo_init; | 
					
						
							|  |  |  |  static int do_foo_init(OPENSSL_CTX *ctx) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |      /* Allocate and initialise some foo resources and associated with ctx */ | 
					
						
							|  |  |  |      return openssl_ctx_onfree(ctx, &foo_cleanup) | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  int foo_some_function(OPENSSL_CTX *ctx) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |     if (!openssl_ctx_run_once(ctx, | 
					
						
							|  |  |  |                               OPENSSL_CTX_FOO_RUN_ONCE_INDEX, | 
					
						
							|  |  |  |                               do_foo_init)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Do some work using foo resources in ctx */ | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-07 00:42:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 SEE ALSO | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | L<OPENSSL_CTX(3)> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 COPYRIGHT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Copyright 2019 The OpenSSL Project Authors. 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 | 
					
						
							|  |  |  | L<https://www.openssl.org/source/license.html>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =cut |