123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- =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> started with "hex", I<value> is assumed to contain
- I<value_n> hexadecimal characters, which are decoded, and the
- resulting bytes become the number stored in the I<< to->data >>
- storage.
- 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> 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 with no
- further checks to the I<< to->data >> storage.
- =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-2020 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
|