| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | =pod | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | =head1 NAME | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-11 07:13:33 +08:00
										 |  |  | OSSL_PARAM_allocate_from_text | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | - 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, | 
					
						
							| 
									
										
										
										
											2020-02-10 11:29:49 +08:00
										 |  |  |                                    size_t value_n, | 
					
						
							|  |  |  |                                    int *found); | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =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). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-08 23:37:37 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 RETURN VALUES | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-08 23:37:37 +08:00
										 |  |  | OSSL_PARAM_allocate_from_text() returns 1 if I<key> was found in | 
					
						
							|  |  |  | I<paramdefs> and there was no other failure, otherwise 0. | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =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> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-08 23:37:37 +08:00
										 |  |  | =item I<data_type> | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-16 02:26:08 +08:00
										 |  |  | =head1 EXAMPLES | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | Code that looked like this: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int mac_ctrl_string(EVP_PKEY_CTX *ctx, const char *value) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |       int rv; | 
					
						
							|  |  |  |       char *stmp, *vtmp = NULL; | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |       stmp = OPENSSL_strdup(value); | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |       if (stmp == NULL) | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |           return -1; | 
					
						
							|  |  |  |       vtmp = strchr(stmp, ':'); | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |       if (vtmp != NULL) | 
					
						
							|  |  |  |           *vtmp++ = '\0'; | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |       rv = EVP_MAC_ctrl_str(ctx, stmp, vtmp); | 
					
						
							|  |  |  |       OPENSSL_free(stmp); | 
					
						
							|  |  |  |       return rv; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |       char *macopt = sk_OPENSSL_STRING_value(macopts, i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |       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 = | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |       OPENSSL_zalloc(sizeof(*params) | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |                      * (sk_OPENSSL_STRING_num(opts) + 1)); | 
					
						
							| 
									
										
										
										
											2019-09-27 14:35:45 +08:00
										 |  |  |   const OSSL_PARAM *paramdefs = EVP_MAC_settable_ctx_params(mac); | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |   size_t params_n; | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |   char *opt = "<unknown>"; | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (params_n = 0; params_n < (size_t)sk_OPENSSL_STRING_num(opts); | 
					
						
							|  |  |  |        params_n++) { | 
					
						
							|  |  |  |       char *stmp, *vtmp = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |       opt = sk_OPENSSL_STRING_value(opts, (int)params_n); | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |       if ((stmp = OPENSSL_strdup(opt)) == NULL | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |               || (vtmp = strchr(stmp, ':')) == NULL) | 
					
						
							|  |  |  |           goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       *vtmp++ = '\0'; | 
					
						
							|  |  |  |       if (!OSSL_PARAM_allocate_from_text(¶ms[params_n], | 
					
						
							|  |  |  |                                          paramdefs, stmp, | 
					
						
							| 
									
										
										
										
											2020-02-10 11:29:49 +08:00
										 |  |  |                                          vtmp, strlen(vtmp), NULL)) | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |           goto err; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   params[params_n] = OSSL_PARAM_construct_end(); | 
					
						
							| 
									
										
										
										
											2020-06-18 16:26:22 +08:00
										 |  |  |   if (!EVP_MAC_CTX_set_params(ctx, params)) | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |       goto err; | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |   while (params_n-- > 0) | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  |       OPENSSL_free(params[params_n].data); | 
					
						
							|  |  |  |   OPENSSL_free(params); | 
					
						
							| 
									
										
										
										
											2019-08-12 11:23:17 +08:00
										 |  |  |   /* ... */ | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |   BIO_printf(bio_err, "MAC parameter error '%s'\n", opt); | 
					
						
							|  |  |  |   ERR_print_errors(bio_err); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 SEE ALSO | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-06 02:03:57 +08:00
										 |  |  | L<OSSL_PARAM(3)>, L<OSSL_PARAM_int(3)> | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | =head1 COPYRIGHT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-23 20:55:52 +08:00
										 |  |  | Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-07-04 00:42:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 |