| =pod |
| |
| =head1 NAME |
| |
| OSSL_PARAM_allocate_from_text |
| - OSSL_PARAM construction utilities |
| |
| =head1 SYNOPSIS |
| |
| #include <openssl/params.h> |
| |
| int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to, |
| const OSSL_PARAM *paramdefs, |
| const char *key, const char *value, |
| size_t value_n, |
| int *found); |
| |
| =head1 DESCRIPTION |
| |
| With OpenSSL before version 3.0, parameters were passed down to or |
| retrieved from algorithm implementations via control functions. |
| Some of these control functions existed in variants that took string |
| parameters, for example L<EVP_PKEY_CTX_ctrl_str(3)>. |
| |
| OpenSSL 3.0 introduces a new mechanism to do the same thing with an |
| array of parameters that contain name, value, value type and value |
| size (see L<OSSL_PARAM(3)> for more information). |
| |
| OSSL_PARAM_allocate_from_text() uses I<key> to look up an item in |
| I<paramdefs>. If an item was found, it converts I<value> to something |
| suitable for that item's I<data_type>, and stores the result in |
| I<< to->data >> as well as its size in I<< to->data_size >>. |
| I<< to->key >> and I<< to->data_type >> are assigned the corresponding |
| values from the item that was found, and I<< to->return_size >> is set |
| to zero. |
| |
| I<< to->data >> is always allocated using L<OPENSSL_zalloc(3)> and |
| needs to be freed by the caller when it's not useful any more, using |
| L<OPENSSL_free(3)>. |
| |
| If I<found> is not NULL, I<*found> is set to 1 if I<key> could be |
| located in I<paramdefs>, and to 0 otherwise. |
| |
| =head2 The use of I<key> and I<value> in detail |
| |
| OSSL_PARAM_allocate_from_text() takes note if I<key> starts with |
| "hex", and will only use the rest of I<key> to look up an item in |
| I<paramdefs> in that case. As an example, if I<key> is "hexid", "id" |
| will be looked up in I<paramdefs>. |
| |
| When an item in I<paramdefs> has been found, I<value> is converted |
| depending on that item's I<data_type>, as follows: |
| |
| =over 4 |
| |
| =item B<OSSL_PARAM_INTEGER> and B<OSSL_PARAM_UNSIGNED_INTEGER> |
| |
| If I<key> didn't start with "hex", I<value> is assumed to contain |
| I<value_n> decimal characters, which are decoded, and the resulting |
| bytes become the number stored in the I<< to->data >> storage. |
| |
| If I<value> starts with "0x", it is assumed to contain I<value_n> |
| hexadecimal characters. |
| |
| If I<key> started with "hex", I<value> is assumed to contain |
| I<value_n> hexadecimal characters without the "0x" prefix. |
| |
| If I<value> contains characters that couldn't be decoded as |
| hexadecimal or decimal characters, OSSL_PARAM_allocate_from_text() |
| considers that an error. |
| |
| =item B<OSSL_PARAM_UTF8_STRING> |
| |
| If I<key> started with "hex", OSSL_PARAM_allocate_from_text() |
| considers that an error. |
| |
| Otherwise, I<value> is considered a C string and is copied to the |
| I<< to->data >> storage. |
| On systems where the native character encoding is EBCDIC, the bytes in |
| I<< to->data >> are converted to ASCII. |
| |
| =item B<OSSL_PARAM_OCTET_STRING> |
| |
| If I<key> started with "hex", I<value> is assumed to contain |
| I<value_n> hexadecimal characters, which are decoded, and the |
| resulting bytes are stored in the I<< to->data >> storage. |
| If I<value> contains characters that couldn't be decoded as |
| hexadecimal or decimal characters, OSSL_PARAM_allocate_from_text() |
| considers that an error. |
| |
| If I<key> didn't start with "hex", I<value_n> bytes from I<value> are |
| copied to the I<< to->data >> storage. |
| |
| =back |
| |
| =head1 RETURN VALUES |
| |
| OSSL_PARAM_allocate_from_text() returns 1 if I<key> was found in |
| I<paramdefs> and there was no other failure, otherwise 0. |
| |
| =head1 NOTES |
| |
| The parameter descriptor array comes from functions dedicated to |
| return them. |
| The following B<OSSL_PARAM> attributes are used: |
| |
| =over 4 |
| |
| =item I<key> |
| |
| =item I<data_type> |
| |
| =item I<data_size> |
| |
| =back |
| |
| All other attributes are ignored. |
| |
| The I<data_size> attribute can be zero, meaning that the parameter it |
| describes expects arbitrary length data. |
| |
| =head1 EXAMPLES |
| |
| Code that looked like this: |
| |
| int mac_ctrl_string(EVP_PKEY_CTX *ctx, const char *value) |
| { |
| int rv; |
| char *stmp, *vtmp = NULL; |
| |
| stmp = OPENSSL_strdup(value); |
| if (stmp == NULL) |
| return -1; |
| vtmp = strchr(stmp, ':'); |
| if (vtmp != NULL) |
| *vtmp++ = '\0'; |
| rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp); |
| OPENSSL_free(stmp); |
| return rv; |
| } |
| |
| ... |
| |
| |
| for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { |
| char *macopt = sk_OPENSSL_STRING_value(macopts, i); |
| |
| if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { |
| BIO_printf(bio_err, |
| "MAC parameter error \"%s\"\n", macopt); |
| ERR_print_errors(bio_err); |
| goto mac_end; |
| } |
| } |
| |
| Can be written like this instead: |
| |
| OSSL_PARAM *params = |
| OPENSSL_zalloc(sizeof(*params) |
| * (sk_OPENSSL_STRING_num(opts) + 1)); |
| const OSSL_PARAM *paramdefs = EVP_MAC_settable_ctx_params(mac); |
| size_t params_n; |
| char *opt = "<unknown>"; |
| |
| for (params_n = 0; params_n < (size_t)sk_OPENSSL_STRING_num(opts); |
| params_n++) { |
| char *stmp, *vtmp = NULL; |
| |
| opt = sk_OPENSSL_STRING_value(opts, (int)params_n); |
| if ((stmp = OPENSSL_strdup(opt)) == NULL |
| || (vtmp = strchr(stmp, ':')) == NULL) |
| goto err; |
| |
| *vtmp++ = '\0'; |
| if (!OSSL_PARAM_allocate_from_text(¶ms[params_n], |
| paramdefs, stmp, |
| vtmp, strlen(vtmp), NULL)) |
| goto err; |
| } |
| params[params_n] = OSSL_PARAM_construct_end(); |
| if (!EVP_MAC_CTX_set_params(ctx, params)) |
| goto err; |
| while (params_n-- > 0) |
| OPENSSL_free(params[params_n].data); |
| OPENSSL_free(params); |
| /* ... */ |
| return; |
| |
| err: |
| BIO_printf(bio_err, "MAC parameter error '%s'\n", opt); |
| ERR_print_errors(bio_err); |
| |
| |
| =head1 SEE ALSO |
| |
| L<OSSL_PARAM(3)>, L<OSSL_PARAM_int(3)> |
| |
| =head1 COPYRIGHT |
| |
| Copyright 2019-2021 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 |