1 | =pod
|
---|
2 |
|
---|
3 | =head1 NAME
|
---|
4 |
|
---|
5 | OSSL_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 |
|
---|
20 | With OpenSSL before version 3.0, parameters were passed down to or
|
---|
21 | retrieved from algorithm implementations via control functions.
|
---|
22 | Some of these control functions existed in variants that took string
|
---|
23 | parameters, for example L<EVP_PKEY_CTX_ctrl_str(3)>.
|
---|
24 |
|
---|
25 | OpenSSL 3.0 introduces a new mechanism to do the same thing with an
|
---|
26 | array of parameters that contain name, value, value type and value
|
---|
27 | size (see L<OSSL_PARAM(3)> for more information).
|
---|
28 |
|
---|
29 | OSSL_PARAM_allocate_from_text() uses I<key> to look up an item in
|
---|
30 | I<paramdefs>. If an item was found, it converts I<value> to something
|
---|
31 | suitable for that item's I<data_type>, and stores the result in
|
---|
32 | I<< to->data >> as well as its size in I<< to->data_size >>.
|
---|
33 | I<< to->key >> and I<< to->data_type >> are assigned the corresponding
|
---|
34 | values from the item that was found, and I<< to->return_size >> is set
|
---|
35 | to zero.
|
---|
36 |
|
---|
37 | I<< to->data >> is always allocated using L<OPENSSL_zalloc(3)> and
|
---|
38 | needs to be freed by the caller when it's not useful any more, using
|
---|
39 | L<OPENSSL_free(3)>.
|
---|
40 |
|
---|
41 | If I<found> is not NULL, I<*found> is set to 1 if I<key> could be
|
---|
42 | located in I<paramdefs>, and to 0 otherwise.
|
---|
43 |
|
---|
44 | =head2 The use of I<key> and I<value> in detail
|
---|
45 |
|
---|
46 | OSSL_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
|
---|
48 | I<paramdefs> in that case. As an example, if I<key> is "hexid", "id"
|
---|
49 | will be looked up in I<paramdefs>.
|
---|
50 |
|
---|
51 | When an item in I<paramdefs> has been found, I<value> is converted
|
---|
52 | depending 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 |
|
---|
58 | If I<key> didn't start with "hex", I<value> is assumed to contain
|
---|
59 | I<value_n> decimal characters, which are decoded, and the resulting
|
---|
60 | bytes become the number stored in the I<< to->data >> storage.
|
---|
61 |
|
---|
62 | If I<value> starts with "0x", it is assumed to contain I<value_n>
|
---|
63 | hexadecimal characters.
|
---|
64 |
|
---|
65 | If I<key> started with "hex", I<value> is assumed to contain
|
---|
66 | I<value_n> hexadecimal characters without the "0x" prefix.
|
---|
67 |
|
---|
68 | If I<value> contains characters that couldn't be decoded as
|
---|
69 | hexadecimal or decimal characters, OSSL_PARAM_allocate_from_text()
|
---|
70 | considers that an error.
|
---|
71 |
|
---|
72 | =item B<OSSL_PARAM_UTF8_STRING>
|
---|
73 |
|
---|
74 | If I<key> started with "hex", OSSL_PARAM_allocate_from_text()
|
---|
75 | considers that an error.
|
---|
76 |
|
---|
77 | Otherwise, I<value> is considered a C string and is copied to the
|
---|
78 | I<< to->data >> storage.
|
---|
79 | On systems where the native character encoding is EBCDIC, the bytes in
|
---|
80 | I<< to->data >> are converted to ASCII.
|
---|
81 |
|
---|
82 | =item B<OSSL_PARAM_OCTET_STRING>
|
---|
83 |
|
---|
84 | If I<key> started with "hex", I<value> is assumed to contain
|
---|
85 | I<value_n> hexadecimal characters, which are decoded, and the
|
---|
86 | resulting bytes are stored in the I<< to->data >> storage.
|
---|
87 | If I<value> contains characters that couldn't be decoded as
|
---|
88 | hexadecimal or decimal characters, OSSL_PARAM_allocate_from_text()
|
---|
89 | considers that an error.
|
---|
90 |
|
---|
91 | If I<key> didn't start with "hex", I<value_n> bytes from I<value> are
|
---|
92 | copied to the I<< to->data >> storage.
|
---|
93 |
|
---|
94 | =back
|
---|
95 |
|
---|
96 | =head1 RETURN VALUES
|
---|
97 |
|
---|
98 | OSSL_PARAM_allocate_from_text() returns 1 if I<key> was found in
|
---|
99 | I<paramdefs> and there was no other failure, otherwise 0.
|
---|
100 |
|
---|
101 | =head1 NOTES
|
---|
102 |
|
---|
103 | The parameter descriptor array comes from functions dedicated to
|
---|
104 | return them.
|
---|
105 | The 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 |
|
---|
117 | All other attributes are ignored.
|
---|
118 |
|
---|
119 | The I<data_size> attribute can be zero, meaning that the parameter it
|
---|
120 | describes expects arbitrary length data.
|
---|
121 |
|
---|
122 | =head1 EXAMPLES
|
---|
123 |
|
---|
124 | Code 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 |
|
---|
156 | Can 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 |
|
---|
196 | L<OSSL_PARAM(3)>, L<OSSL_PARAM_int(3)>
|
---|
197 |
|
---|
198 | =head1 COPYRIGHT
|
---|
199 |
|
---|
200 | Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
|
---|
201 |
|
---|
202 | Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
203 | this file except in compliance with the License. You can obtain a copy
|
---|
204 | in the file LICENSE in the source distribution or at
|
---|
205 | L<https://www.openssl.org/source/license.html>.
|
---|
206 |
|
---|
207 | =cut
|
---|