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(&params[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