1b077aed3SPierre Pronchery=pod 2b077aed3SPierre Pronchery 3b077aed3SPierre Pronchery=head1 NAME 4b077aed3SPierre Pronchery 5b077aed3SPierre ProncheryOSSL_PARAM - a structure to pass or request object parameters 6b077aed3SPierre Pronchery 7b077aed3SPierre Pronchery=head1 SYNOPSIS 8b077aed3SPierre Pronchery 9b077aed3SPierre Pronchery #include <openssl/core.h> 10b077aed3SPierre Pronchery 11b077aed3SPierre Pronchery typedef struct ossl_param_st OSSL_PARAM; 12b077aed3SPierre Pronchery struct ossl_param_st { 13b077aed3SPierre Pronchery const char *key; /* the name of the parameter */ 14*0d0c8621SEnji Cooper unsigned int data_type; /* declare what kind of content is in data */ 15b077aed3SPierre Pronchery void *data; /* value being passed in or out */ 16b077aed3SPierre Pronchery size_t data_size; /* data size */ 17b077aed3SPierre Pronchery size_t return_size; /* returned size */ 18b077aed3SPierre Pronchery }; 19b077aed3SPierre Pronchery 20b077aed3SPierre Pronchery=head1 DESCRIPTION 21b077aed3SPierre Pronchery 22b077aed3SPierre ProncheryB<OSSL_PARAM> is a type that allows passing arbitrary data for some 23b077aed3SPierre Proncheryobject between two parties that have no or very little shared 24b077aed3SPierre Proncheryknowledge about their respective internal structures for that object. 25b077aed3SPierre Pronchery 26b077aed3SPierre ProncheryA typical usage example could be an application that wants to set some 27b077aed3SPierre Proncheryparameters for an object, or wants to find out some parameters of an 28b077aed3SPierre Proncheryobject. 29b077aed3SPierre Pronchery 30b077aed3SPierre ProncheryArrays of this type can be used for the following purposes: 31b077aed3SPierre Pronchery 32b077aed3SPierre Pronchery=over 4 33b077aed3SPierre Pronchery 34b077aed3SPierre Pronchery=item * Setting parameters for some object 35b077aed3SPierre Pronchery 36b077aed3SPierre ProncheryThe caller sets up the B<OSSL_PARAM> array and calls some function 37b077aed3SPierre Pronchery(the I<setter>) that has intimate knowledge about the object that can 38b077aed3SPierre Proncherytake the data from the B<OSSL_PARAM> array and assign them in a 39b077aed3SPierre Proncherysuitable form for the internal structure of the object. 40b077aed3SPierre Pronchery 41b077aed3SPierre Pronchery=item * Request parameters of some object 42b077aed3SPierre Pronchery 43b077aed3SPierre ProncheryThe caller (the I<requester>) sets up the B<OSSL_PARAM> array and 44b077aed3SPierre Proncherycalls some function (the I<responder>) that has intimate knowledge 45b077aed3SPierre Proncheryabout the object, which can take the internal data of the object and 46b077aed3SPierre Proncherycopy (possibly convert) that to the memory prepared by the 47b077aed3SPierre ProncheryI<requester> and pointed at with the B<OSSL_PARAM> I<data>. 48b077aed3SPierre Pronchery 49b077aed3SPierre Pronchery=item * Request parameter descriptors 50b077aed3SPierre Pronchery 51b077aed3SPierre ProncheryThe caller gets an array of constant B<OSSL_PARAM>, which describe 52b077aed3SPierre Proncheryavailable parameters and some of their properties; name, data type and 53b077aed3SPierre Proncheryexpected data size. 54b077aed3SPierre ProncheryFor a detailed description of each field for this use, see the field 55b077aed3SPierre Proncherydescriptions below. 56b077aed3SPierre Pronchery 57b077aed3SPierre ProncheryThe caller may then use the information from this descriptor array to 58b077aed3SPierre Proncherybuild up its own B<OSSL_PARAM> array to pass down to a I<setter> or 59b077aed3SPierre ProncheryI<responder>. 60b077aed3SPierre Pronchery 61b077aed3SPierre Pronchery=back 62b077aed3SPierre Pronchery 63b077aed3SPierre ProncheryNormally, the order of the an B<OSSL_PARAM> array is not relevant. 64b077aed3SPierre ProncheryHowever, if the I<responder> can handle multiple elements with the 65b077aed3SPierre Proncherysame key, those elements must be handled in the order they are in. 66b077aed3SPierre Pronchery 67b077aed3SPierre ProncheryAn B<OSSL_PARAM> array must have a terminating element, where I<key> 68b077aed3SPierre Proncheryis NULL. The usual full terminating template is: 69b077aed3SPierre Pronchery 70b077aed3SPierre Pronchery { NULL, 0, NULL, 0, 0 } 71b077aed3SPierre Pronchery 72b077aed3SPierre ProncheryThis can also be specified using L<OSSL_PARAM_END(3)>. 73b077aed3SPierre Pronchery 74b077aed3SPierre Pronchery=head2 Functional support 75b077aed3SPierre Pronchery 76b077aed3SPierre ProncheryLibcrypto offers a limited set of helper functions to handle 77b077aed3SPierre ProncheryB<OSSL_PARAM> items and arrays, please see L<OSSL_PARAM_get_int(3)>. 78b077aed3SPierre ProncheryDevelopers are free to extend or replace those as they see fit. 79b077aed3SPierre Pronchery 80b077aed3SPierre Pronchery=head2 B<OSSL_PARAM> fields 81b077aed3SPierre Pronchery 82b077aed3SPierre Pronchery=over 4 83b077aed3SPierre Pronchery 84b077aed3SPierre Pronchery=item I<key> 85b077aed3SPierre Pronchery 86b077aed3SPierre ProncheryThe identity of the parameter in the form of a string. 87b077aed3SPierre Pronchery 88b077aed3SPierre ProncheryIn an B<OSSL_PARAM> array, an item with this field set to NULL is 89b077aed3SPierre Proncheryconsidered a terminating item. 90b077aed3SPierre Pronchery 91b077aed3SPierre Pronchery=item I<data_type> 92b077aed3SPierre Pronchery 93b077aed3SPierre ProncheryThe I<data_type> is a value that describes the type and organization of 94b077aed3SPierre Proncherythe data. 95b077aed3SPierre ProncherySee L</Supported types> below for a description of the types. 96b077aed3SPierre Pronchery 97b077aed3SPierre Pronchery=item I<data> 98b077aed3SPierre Pronchery 99b077aed3SPierre Pronchery=item I<data_size> 100b077aed3SPierre Pronchery 101b077aed3SPierre ProncheryI<data> is a pointer to the memory where the parameter data is (when 102b077aed3SPierre Proncherysetting parameters) or shall (when requesting parameters) be stored, 103b077aed3SPierre Proncheryand I<data_size> is its size in bytes. 104b077aed3SPierre ProncheryThe organization of the data depends on the parameter type and flag. 105b077aed3SPierre Pronchery 106b077aed3SPierre ProncheryThe I<data_size> needs special attention with the parameter type 107b077aed3SPierre ProncheryB<OSSL_PARAM_UTF8_STRING> in relation to C strings. When setting 108b077aed3SPierre Proncheryparameters, the size should be set to the length of the string, not 109b077aed3SPierre Proncherycounting the terminating NUL byte. When requesting parameters, the 110b077aed3SPierre Proncherysize should be set to the size of the buffer to be populated, which 111aa795734SPierre Proncheryshould accommodate enough space for a terminating NUL byte. 112b077aed3SPierre Pronchery 113b077aed3SPierre ProncheryWhen I<requesting parameters>, it's acceptable for I<data> to be NULL. 114b077aed3SPierre ProncheryThis can be used by the I<requester> to figure out dynamically exactly 115b077aed3SPierre Proncheryhow much buffer space is needed to store the parameter data. 116b077aed3SPierre ProncheryIn this case, I<data_size> is ignored. 117b077aed3SPierre Pronchery 118b077aed3SPierre ProncheryWhen the B<OSSL_PARAM> is used as a parameter descriptor, I<data> 119b077aed3SPierre Proncheryshould be ignored. 120b077aed3SPierre ProncheryIf I<data_size> is zero, it means that an arbitrary data size is 121b077aed3SPierre Proncheryaccepted, otherwise it specifies the maximum size allowed. 122b077aed3SPierre Pronchery 123b077aed3SPierre Pronchery=item I<return_size> 124b077aed3SPierre Pronchery 125b077aed3SPierre ProncheryWhen an array of B<OSSL_PARAM> is used to request data, the 126b077aed3SPierre ProncheryI<responder> must set this field to indicate size of the parameter 127b077aed3SPierre Proncherydata, including padding as the case may be. 128b077aed3SPierre ProncheryIn case the I<data_size> is an unsuitable size for the data, the 129b077aed3SPierre ProncheryI<responder> must still set this field to indicate the minimum data 130b077aed3SPierre Proncherysize required. 131b077aed3SPierre Pronchery(further notes on this in L</NOTES> below). 132b077aed3SPierre Pronchery 133b077aed3SPierre ProncheryWhen the B<OSSL_PARAM> is used as a parameter descriptor, 134b077aed3SPierre ProncheryI<return_size> should be ignored. 135b077aed3SPierre Pronchery 136b077aed3SPierre Pronchery=back 137b077aed3SPierre Pronchery 138b077aed3SPierre ProncheryB<NOTE:> 139b077aed3SPierre Pronchery 140b077aed3SPierre ProncheryThe key names and associated types are defined by the entity that 141b077aed3SPierre Proncheryoffers these parameters, i.e. names for parameters provided by the 142b077aed3SPierre ProncheryOpenSSL libraries are defined by the libraries, and names for 143b077aed3SPierre Proncheryparameters provided by providers are defined by those providers, 144b077aed3SPierre Proncheryexcept for the pointer form of strings (see data type descriptions 145b077aed3SPierre Proncherybelow). 146b077aed3SPierre ProncheryEntities that want to set or request parameters need to know what 147b077aed3SPierre Proncherythose keys are and of what type, any functionality between those two 148b077aed3SPierre Proncheryentities should remain oblivious and just pass the B<OSSL_PARAM> array 149b077aed3SPierre Proncheryalong. 150b077aed3SPierre Pronchery 151b077aed3SPierre Pronchery=head2 Supported types 152b077aed3SPierre Pronchery 153b077aed3SPierre ProncheryThe I<data_type> field can be one of the following types: 154b077aed3SPierre Pronchery 155b077aed3SPierre Pronchery=over 4 156b077aed3SPierre Pronchery 157b077aed3SPierre Pronchery=item B<OSSL_PARAM_INTEGER> 158b077aed3SPierre Pronchery 159b077aed3SPierre Pronchery=item B<OSSL_PARAM_UNSIGNED_INTEGER> 160b077aed3SPierre Pronchery 161b077aed3SPierre ProncheryThe parameter data is an integer (signed or unsigned) of arbitrary 162b077aed3SPierre Proncherylength, organized in native form, i.e. most significant byte first on 163b077aed3SPierre ProncheryBig-Endian systems, and least significant byte first on Little-Endian 164b077aed3SPierre Proncherysystems. 165b077aed3SPierre Pronchery 166b077aed3SPierre Pronchery=item B<OSSL_PARAM_REAL> 167b077aed3SPierre Pronchery 168b077aed3SPierre ProncheryThe parameter data is a floating point value in native form. 169b077aed3SPierre Pronchery 170b077aed3SPierre Pronchery=item B<OSSL_PARAM_UTF8_STRING> 171b077aed3SPierre Pronchery 172b077aed3SPierre ProncheryThe parameter data is a printable string. 173b077aed3SPierre Pronchery 174b077aed3SPierre Pronchery=item B<OSSL_PARAM_OCTET_STRING> 175b077aed3SPierre Pronchery 176b077aed3SPierre ProncheryThe parameter data is an arbitrary string of bytes. 177b077aed3SPierre Pronchery 178b077aed3SPierre Pronchery=item B<OSSL_PARAM_UTF8_PTR> 179b077aed3SPierre Pronchery 180b077aed3SPierre ProncheryThe parameter data is a pointer to a printable string. 181b077aed3SPierre Pronchery 182b077aed3SPierre ProncheryThe difference between this and B<OSSL_PARAM_UTF8_STRING> is that I<data> 183b077aed3SPierre Proncherydoesn't point directly at the data, but to a pointer that points to the data. 184b077aed3SPierre Pronchery 185b077aed3SPierre ProncheryIf there is any uncertainty about which to use, B<OSSL_PARAM_UTF8_STRING> is 186b077aed3SPierre Proncheryalmost certainly the correct choice. 187b077aed3SPierre Pronchery 188b077aed3SPierre ProncheryThis is used to indicate that constant data is or will be passed, 189b077aed3SPierre Proncheryand there is therefore no need to copy the data that is passed, just 190b077aed3SPierre Proncherythe pointer to it. 191b077aed3SPierre Pronchery 192b077aed3SPierre ProncheryI<data_size> must be set to the size of the data, not the size of the 193b077aed3SPierre Proncherypointer to the data. 194b077aed3SPierre ProncheryIf this is used in a parameter request, 195b077aed3SPierre ProncheryI<data_size> is not relevant. However, the I<responder> will set 196b077aed3SPierre ProncheryI<return_size> to the size of the data. 197b077aed3SPierre Pronchery 198b077aed3SPierre ProncheryNote that the use of this type is B<fragile> and can only be safely 199b077aed3SPierre Proncheryused for data that remains constant and in a constant location for a 200b077aed3SPierre Proncherylong enough duration (such as the life-time of the entity that 201b077aed3SPierre Proncheryoffers these parameters). 202b077aed3SPierre Pronchery 203b077aed3SPierre Pronchery=item B<OSSL_PARAM_OCTET_PTR> 204b077aed3SPierre Pronchery 205b077aed3SPierre ProncheryThe parameter data is a pointer to an arbitrary string of bytes. 206b077aed3SPierre Pronchery 207b077aed3SPierre ProncheryThe difference between this and B<OSSL_PARAM_OCTET_STRING> is that 208b077aed3SPierre ProncheryI<data> doesn't point directly at the data, but to a pointer that 209b077aed3SPierre Proncherypoints to the data. 210b077aed3SPierre Pronchery 211b077aed3SPierre ProncheryIf there is any uncertainty about which to use, B<OSSL_PARAM_OCTET_STRING> is 212b077aed3SPierre Proncheryalmost certainly the correct choice. 213b077aed3SPierre Pronchery 214b077aed3SPierre ProncheryThis is used to indicate that constant data is or will be passed, and 215b077aed3SPierre Proncherythere is therefore no need to copy the data that is passed, just the 216b077aed3SPierre Proncherypointer to it. 217b077aed3SPierre Pronchery 218b077aed3SPierre ProncheryI<data_size> must be set to the size of the data, not the size of the 219b077aed3SPierre Proncherypointer to the data. 220b077aed3SPierre ProncheryIf this is used in a parameter request, 221b077aed3SPierre ProncheryI<data_size> is not relevant. However, the I<responder> will set 222b077aed3SPierre ProncheryI<return_size> to the size of the data. 223b077aed3SPierre Pronchery 224b077aed3SPierre ProncheryNote that the use of this type is B<fragile> and can only be safely 225b077aed3SPierre Proncheryused for data that remains constant and in a constant location for a 226b077aed3SPierre Proncherylong enough duration (such as the life-time of the entity that 227b077aed3SPierre Proncheryoffers these parameters). 228b077aed3SPierre Pronchery 229b077aed3SPierre Pronchery=back 230b077aed3SPierre Pronchery 231b077aed3SPierre Pronchery=head1 NOTES 232b077aed3SPierre Pronchery 233b077aed3SPierre ProncheryBoth when setting and requesting parameters, the functions that are 234b077aed3SPierre Proncherycalled will have to decide what is and what is not an error. 235b077aed3SPierre ProncheryThe recommended behaviour is: 236b077aed3SPierre Pronchery 237b077aed3SPierre Pronchery=over 4 238b077aed3SPierre Pronchery 239b077aed3SPierre Pronchery=item * 240b077aed3SPierre Pronchery 241b077aed3SPierre ProncheryKeys that a I<setter> or I<responder> doesn't recognise should simply 242b077aed3SPierre Proncherybe ignored. 243b077aed3SPierre ProncheryThat in itself isn't an error. 244b077aed3SPierre Pronchery 245b077aed3SPierre Pronchery=item * 246b077aed3SPierre Pronchery 247b077aed3SPierre ProncheryIf the keys that a called I<setter> recognises form a consistent 248b077aed3SPierre Proncheryenough set of data, that call should succeed. 249b077aed3SPierre Pronchery 250b077aed3SPierre Pronchery=item * 251b077aed3SPierre Pronchery 252b077aed3SPierre ProncheryApart from the I<return_size>, a I<responder> must never change the fields 253b077aed3SPierre Proncheryof an B<OSSL_PARAM>. 254b077aed3SPierre ProncheryTo return a value, it should change the contents of the memory that 255b077aed3SPierre ProncheryI<data> points at. 256b077aed3SPierre Pronchery 257b077aed3SPierre Pronchery=item * 258b077aed3SPierre Pronchery 259b077aed3SPierre ProncheryIf the data type for a key that it's associated with is incorrect, 260b077aed3SPierre Proncherythe called function may return an error. 261b077aed3SPierre Pronchery 262b077aed3SPierre ProncheryThe called function may also try to convert the data to a suitable 263b077aed3SPierre Proncheryform (for example, it's plausible to pass a large number as an octet 264b077aed3SPierre Proncherystring, so even though a given key is defined as an 265b077aed3SPierre ProncheryB<OSSL_PARAM_UNSIGNED_INTEGER>, is plausible to pass the value as an 266b077aed3SPierre ProncheryB<OSSL_PARAM_OCTET_STRING>), but this is in no way mandatory. 267b077aed3SPierre Pronchery 268b077aed3SPierre Pronchery=item * 269b077aed3SPierre Pronchery 270b077aed3SPierre ProncheryIf I<data> for a B<OSSL_PARAM_OCTET_STRING> or a 271b077aed3SPierre ProncheryB<OSSL_PARAM_UTF8_STRING> is NULL, the I<responder> should 272b077aed3SPierre Proncheryset I<return_size> to the size of the item to be returned 273b077aed3SPierre Proncheryand return success. Later the responder will be called again 274b077aed3SPierre Proncherywith I<data> pointing at the place for the value to be put. 275b077aed3SPierre Pronchery 276b077aed3SPierre Pronchery=item * 277b077aed3SPierre Pronchery 278b077aed3SPierre ProncheryIf a I<responder> finds that some data sizes are too small for the 279b077aed3SPierre Proncheryrequested data, it must set I<return_size> for each such 280b077aed3SPierre ProncheryB<OSSL_PARAM> item to the minimum required size, and eventually return 281b077aed3SPierre Proncheryan error. 282b077aed3SPierre Pronchery 283b077aed3SPierre Pronchery=item * 284b077aed3SPierre Pronchery 285b077aed3SPierre ProncheryFor the integer type parameters (B<OSSL_PARAM_UNSIGNED_INTEGER> and 286b077aed3SPierre ProncheryB<OSSL_PARAM_INTEGER>), a I<responder> may choose to return an error 287b077aed3SPierre Proncheryif the I<data_size> isn't a suitable size (even if I<data_size> is 288b077aed3SPierre Proncherybigger than needed). If the I<responder> finds the size suitable, it 289b077aed3SPierre Proncherymust fill all I<data_size> bytes and ensure correct padding for the 290b077aed3SPierre Proncherynative endianness, and set I<return_size> to the same value as 291b077aed3SPierre ProncheryI<data_size>. 292b077aed3SPierre Pronchery 293b077aed3SPierre Pronchery=back 294b077aed3SPierre Pronchery 295b077aed3SPierre Pronchery=begin comment RETURN VALUES doesn't make sense for a manual that only 296b077aed3SPierre Proncherydescribes a type, but document checkers still want that section, and 297b077aed3SPierre Proncheryto have more than just the section title. 298b077aed3SPierre Pronchery 299b077aed3SPierre Pronchery=head1 RETURN VALUES 300b077aed3SPierre Pronchery 301b077aed3SPierre Proncherytxt 302b077aed3SPierre Pronchery 303b077aed3SPierre Pronchery=end comment 304b077aed3SPierre Pronchery 305b077aed3SPierre Pronchery=head1 EXAMPLES 306b077aed3SPierre Pronchery 307b077aed3SPierre ProncheryA couple of examples to just show how B<OSSL_PARAM> arrays could be 308b077aed3SPierre Proncheryset up. 309b077aed3SPierre Pronchery 310b077aed3SPierre Pronchery=head3 Example 1 311b077aed3SPierre Pronchery 312b077aed3SPierre ProncheryThis example is for setting parameters on some object: 313b077aed3SPierre Pronchery 314b077aed3SPierre Pronchery #include <openssl/core.h> 315b077aed3SPierre Pronchery 316b077aed3SPierre Pronchery const char *foo = "some string"; 317b077aed3SPierre Pronchery size_t foo_l = strlen(foo); 318b077aed3SPierre Pronchery const char bar[] = "some other string"; 319b077aed3SPierre Pronchery OSSL_PARAM set[] = { 320b077aed3SPierre Pronchery { "foo", OSSL_PARAM_UTF8_PTR, &foo, foo_l, 0 }, 321b077aed3SPierre Pronchery { "bar", OSSL_PARAM_UTF8_STRING, (void *)&bar, sizeof(bar) - 1, 0 }, 322b077aed3SPierre Pronchery { NULL, 0, NULL, 0, 0 } 323b077aed3SPierre Pronchery }; 324b077aed3SPierre Pronchery 325b077aed3SPierre Pronchery=head3 Example 2 326b077aed3SPierre Pronchery 327b077aed3SPierre ProncheryThis example is for requesting parameters on some object: 328b077aed3SPierre Pronchery 329b077aed3SPierre Pronchery const char *foo = NULL; 330b077aed3SPierre Pronchery size_t foo_l; 331b077aed3SPierre Pronchery char bar[1024]; 332b077aed3SPierre Pronchery size_t bar_l; 333b077aed3SPierre Pronchery OSSL_PARAM request[] = { 334b077aed3SPierre Pronchery { "foo", OSSL_PARAM_UTF8_PTR, &foo, 0 /*irrelevant*/, 0 }, 335b077aed3SPierre Pronchery { "bar", OSSL_PARAM_UTF8_STRING, &bar, sizeof(bar), 0 }, 336b077aed3SPierre Pronchery { NULL, 0, NULL, 0, 0 } 337b077aed3SPierre Pronchery }; 338b077aed3SPierre Pronchery 339b077aed3SPierre ProncheryA I<responder> that receives this array (as I<params> in this example) 340b077aed3SPierre Proncherycould fill in the parameters like this: 341b077aed3SPierre Pronchery 342b077aed3SPierre Pronchery /* OSSL_PARAM *params */ 343b077aed3SPierre Pronchery 344b077aed3SPierre Pronchery int i; 345b077aed3SPierre Pronchery 346b077aed3SPierre Pronchery for (i = 0; params[i].key != NULL; i++) { 347b077aed3SPierre Pronchery if (strcmp(params[i].key, "foo") == 0) { 348b077aed3SPierre Pronchery *(char **)params[i].data = "foo value"; 349b077aed3SPierre Pronchery params[i].return_size = 9; /* length of "foo value" string */ 350b077aed3SPierre Pronchery } else if (strcmp(params[i].key, "bar") == 0) { 351b077aed3SPierre Pronchery memcpy(params[i].data, "bar value", 10); 352b077aed3SPierre Pronchery params[i].return_size = 9; /* length of "bar value" string */ 353b077aed3SPierre Pronchery } 354b077aed3SPierre Pronchery /* Ignore stuff we don't know */ 355b077aed3SPierre Pronchery } 356b077aed3SPierre Pronchery 357b077aed3SPierre Pronchery=head1 SEE ALSO 358b077aed3SPierre Pronchery 359b077aed3SPierre ProncheryL<openssl-core.h(7)>, L<OSSL_PARAM_get_int(3)>, L<OSSL_PARAM_dup(3)> 360b077aed3SPierre Pronchery 361b077aed3SPierre Pronchery=head1 HISTORY 362b077aed3SPierre Pronchery 363b077aed3SPierre ProncheryB<OSSL_PARAM> was added in OpenSSL 3.0. 364b077aed3SPierre Pronchery 365b077aed3SPierre Pronchery=head1 COPYRIGHT 366b077aed3SPierre Pronchery 367b077aed3SPierre ProncheryCopyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. 368b077aed3SPierre Pronchery 369b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License"). You may not use 370b077aed3SPierre Proncherythis file except in compliance with the License. You can obtain a copy 371b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at 372b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>. 373b077aed3SPierre Pronchery 374b077aed3SPierre Pronchery=cut 375