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