1=pod 2 3=head1 NAME 4 5OSSL_PARAM_allocate_from_text 6- OSSL_PARAM construction utilities 7 8=head1 SYNOPSIS 9 10 #include <openssl/params.h> 11 12 int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to, 13 const OSSL_PARAM *paramdefs, 14 const char *key, const char *value, 15 size_t value_n, 16 int *found); 17 18=head1 DESCRIPTION 19 20With OpenSSL before version 3.0, parameters were passed down to or 21retrieved from algorithm implementations via control functions. 22Some of these control functions existed in variants that took string 23parameters, for example L<EVP_PKEY_CTX_ctrl_str(3)>. 24 25OpenSSL 3.0 introduces a new mechanism to do the same thing with an 26array of parameters that contain name, value, value type and value 27size (see L<OSSL_PARAM(3)> for more information). 28 29OSSL_PARAM_allocate_from_text() uses I<key> to look up an item in 30I<paramdefs>. If an item was found, it converts I<value> to something 31suitable for that item's I<data_type>, and stores the result in 32I<< to->data >> as well as its size in I<< to->data_size >>. 33I<< to->key >> and I<< to->data_type >> are assigned the corresponding 34values from the item that was found, and I<< to->return_size >> is set 35to zero. 36 37I<< to->data >> is always allocated using L<OPENSSL_zalloc(3)> and 38needs to be freed by the caller when it's not useful any more, using 39L<OPENSSL_free(3)>. 40 41If I<found> is not NULL, I<*found> is set to 1 if I<key> could be 42located in I<paramdefs>, and to 0 otherwise. 43 44=head2 The use of I<key> and I<value> in detail 45 46OSSL_PARAM_allocate_from_text() takes note if I<key> starts with 47"hex", and will only use the rest of I<key> to look up an item in 48I<paramdefs> in that case. As an example, if I<key> is "hexid", "id" 49will be looked up in I<paramdefs>. 50 51When an item in I<paramdefs> has been found, I<value> is converted 52depending on that item's I<data_type>, as follows: 53 54=over 4 55 56=item B<OSSL_PARAM_INTEGER> and B<OSSL_PARAM_UNSIGNED_INTEGER> 57 58If I<key> didn't start with "hex", I<value> is assumed to contain 59I<value_n> decimal characters, which are decoded, and the resulting 60bytes become the number stored in the I<< to->data >> storage. 61 62If I<value> starts with "0x", it is assumed to contain I<value_n> 63hexadecimal characters. 64 65If I<key> started with "hex", I<value> is assumed to contain 66I<value_n> hexadecimal characters without the "0x" prefix. 67 68If I<value> contains characters that couldn't be decoded as 69hexadecimal or decimal characters, OSSL_PARAM_allocate_from_text() 70considers that an error. 71 72=item B<OSSL_PARAM_UTF8_STRING> 73 74If I<key> started with "hex", OSSL_PARAM_allocate_from_text() 75considers that an error. 76 77Otherwise, I<value> is considered a C string and is copied to the 78I<< to->data >> storage. 79On systems where the native character encoding is EBCDIC, the bytes in 80I<< to->data >> are converted to ASCII. 81 82=item B<OSSL_PARAM_OCTET_STRING> 83 84If I<key> started with "hex", I<value> is assumed to contain 85I<value_n> hexadecimal characters, which are decoded, and the 86resulting bytes are stored in the I<< to->data >> storage. 87If I<value> contains characters that couldn't be decoded as 88hexadecimal or decimal characters, OSSL_PARAM_allocate_from_text() 89considers that an error. 90 91If I<key> didn't start with "hex", I<value_n> bytes from I<value> are 92copied to the I<< to->data >> storage. 93 94=back 95 96=head1 RETURN VALUES 97 98OSSL_PARAM_allocate_from_text() returns 1 if I<key> was found in 99I<paramdefs> and there was no other failure, otherwise 0. 100 101=head1 NOTES 102 103The parameter descriptor array comes from functions dedicated to 104return them. 105The following L<OSSL_PARAM(3)> attributes are used: 106 107=over 4 108 109=item I<key> 110 111=item I<data_type> 112 113=item I<data_size> 114 115=back 116 117All other attributes are ignored. 118 119The I<data_size> attribute can be zero, meaning that the parameter it 120describes expects arbitrary length data. 121 122=head1 EXAMPLES 123 124Code that looked like this: 125 126 int mac_ctrl_string(EVP_PKEY_CTX *ctx, const char *value) 127 { 128 int rv; 129 char *stmp, *vtmp = NULL; 130 131 stmp = OPENSSL_strdup(value); 132 if (stmp == NULL) 133 return -1; 134 vtmp = strchr(stmp, ':'); 135 if (vtmp != NULL) 136 *vtmp++ = '\0'; 137 rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp); 138 OPENSSL_free(stmp); 139 return rv; 140 } 141 142 ... 143 144 145 for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { 146 char *macopt = sk_OPENSSL_STRING_value(macopts, i); 147 148 if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { 149 BIO_printf(bio_err, 150 "MAC parameter error \"%s\"\n", macopt); 151 ERR_print_errors(bio_err); 152 goto mac_end; 153 } 154 } 155 156Can be written like this instead: 157 158 OSSL_PARAM *params = 159 OPENSSL_zalloc(sizeof(*params) 160 * (sk_OPENSSL_STRING_num(opts) + 1)); 161 const OSSL_PARAM *paramdefs = EVP_MAC_settable_ctx_params(mac); 162 size_t params_n; 163 char *opt = "<unknown>"; 164 165 for (params_n = 0; params_n < (size_t)sk_OPENSSL_STRING_num(opts); 166 params_n++) { 167 char *stmp, *vtmp = NULL; 168 169 opt = sk_OPENSSL_STRING_value(opts, (int)params_n); 170 if ((stmp = OPENSSL_strdup(opt)) == NULL 171 || (vtmp = strchr(stmp, ':')) == NULL) 172 goto err; 173 174 *vtmp++ = '\0'; 175 if (!OSSL_PARAM_allocate_from_text(¶ms[params_n], 176 paramdefs, stmp, 177 vtmp, strlen(vtmp), NULL)) 178 goto err; 179 } 180 params[params_n] = OSSL_PARAM_construct_end(); 181 if (!EVP_MAC_CTX_set_params(ctx, params)) 182 goto err; 183 while (params_n-- > 0) 184 OPENSSL_free(params[params_n].data); 185 OPENSSL_free(params); 186 /* ... */ 187 return; 188 189 err: 190 BIO_printf(bio_err, "MAC parameter error '%s'\n", opt); 191 ERR_print_errors(bio_err); 192 193 194=head1 SEE ALSO 195 196L<OSSL_PARAM(3)>, L<OSSL_PARAM_int(3)> 197 198=head1 COPYRIGHT 199 200Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 201 202Licensed under the Apache License 2.0 (the "License"). You may not use 203this file except in compliance with the License. You can obtain a copy 204in the file LICENSE in the source distribution or at 205L<https://www.openssl.org/source/license.html>. 206 207=cut 208