]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/params.c
Implement the param types that aren't explicitly lengthened (e.g. int) in terms
[thirdparty/openssl.git] / crypto / params.c
1 /*
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11 #include <string.h>
12 #include <openssl/params.h>
13 #include "internal/thread_once.h"
14
15 #define SET_RETURN_SIZE(p, sz) \
16 if ((p)->return_size != NULL) \
17 *(p)->return_size = (sz)
18
19 const OSSL_PARAM *OSSL_PARAM_locate(const OSSL_PARAM *p, const char *key)
20 {
21 if (p != NULL && key != NULL)
22 for (; p->key != NULL; p++)
23 if (strcmp(key, p->key) == 0)
24 return p;
25 return NULL;
26 }
27
28 static OSSL_PARAM ossl_param_construct(const char *key, unsigned int data_type,
29 void *data, size_t data_size,
30 size_t *return_size)
31 {
32 OSSL_PARAM res;
33
34 res.key = key;
35 res.data_type = data_type;
36 res.data = data;
37 res.data_size = data_size;
38 res.return_size = return_size;
39 return res;
40 }
41
42 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val)
43 {
44 switch (sizeof(int)) {
45 case sizeof(int32_t):
46 return OSSL_PARAM_get_int32(p, (int32_t *)val);
47 case sizeof(int64_t):
48 return OSSL_PARAM_get_int64(p, (int64_t *)val);
49 }
50 return 0;
51 }
52
53 int OSSL_PARAM_set_int(const OSSL_PARAM *p, int val)
54 {
55 switch (sizeof(int)) {
56 case sizeof(int32_t):
57 return OSSL_PARAM_set_int32(p, (int32_t)val);
58 case sizeof(int64_t):
59 return OSSL_PARAM_set_int64(p, (int64_t)val);
60 }
61 return 0;
62 }
63
64 OSSL_PARAM OSSL_PARAM_construct_int(const char *key, int *buf, size_t *rsize)
65 {
66 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int),
67 rsize);
68 }
69
70 int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val)
71 {
72 switch (sizeof(unsigned int)) {
73 case sizeof(uint32_t):
74 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
75 case sizeof(uint64_t):
76 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
77 }
78 return 0;
79 }
80
81 int OSSL_PARAM_set_uint(const OSSL_PARAM *p, unsigned int val)
82 {
83 switch (sizeof(unsigned int)) {
84 case sizeof(uint32_t):
85 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
86 case sizeof(uint64_t):
87 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
88 }
89 return 0;
90 }
91
92 OSSL_PARAM OSSL_PARAM_construct_uint(const char *key, unsigned int *buf,
93 size_t *rsize)
94 {
95 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
96 sizeof(unsigned int), rsize);
97 }
98
99 int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val)
100 {
101 switch (sizeof(long int)) {
102 case sizeof(int32_t):
103 return OSSL_PARAM_get_int32(p, (int32_t *)val);
104 case sizeof(int64_t):
105 return OSSL_PARAM_get_int64(p, (int64_t *)val);
106 }
107 return 0;
108 }
109
110 int OSSL_PARAM_set_long(const OSSL_PARAM *p, long int val)
111 {
112 switch (sizeof(long int)) {
113 case sizeof(int32_t):
114 return OSSL_PARAM_set_int32(p, (int32_t)val);
115 case sizeof(int64_t):
116 return OSSL_PARAM_set_int64(p, (int64_t)val);
117 }
118 return 0;
119 }
120
121 OSSL_PARAM OSSL_PARAM_construct_long(const char *key, long int *buf,
122 size_t *rsize)
123 {
124 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(long int),
125 rsize);
126 }
127
128 int OSSL_PARAM_get_ulong(const OSSL_PARAM *p, unsigned long int *val)
129 {
130 switch (sizeof(unsigned long int)) {
131 case sizeof(uint32_t):
132 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
133 case sizeof(uint64_t):
134 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
135 }
136 return 0;
137 }
138
139 int OSSL_PARAM_set_ulong(const OSSL_PARAM *p, unsigned long int val)
140 {
141 switch (sizeof(unsigned long int)) {
142 case sizeof(uint32_t):
143 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
144 case sizeof(uint64_t):
145 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
146 }
147 return 0;
148 }
149
150 OSSL_PARAM OSSL_PARAM_construct_ulong(const char *key, unsigned long int *buf,
151 size_t *rsize)
152 {
153 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
154 sizeof(unsigned long int), rsize);
155 }
156
157 int OSSL_PARAM_get_int32(const OSSL_PARAM *p, int32_t *val)
158 {
159 if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
160 return 0;
161
162 if (p->data_size == sizeof(int32_t)) {
163 *val = *(const int32_t *)p->data;
164 return 1;
165 }
166 return 0;
167 }
168
169 int OSSL_PARAM_set_int32(const OSSL_PARAM *p, int32_t val)
170 {
171 if (p == NULL)
172 return 0;
173 SET_RETURN_SIZE(p, 0);
174 if (p->data_type != OSSL_PARAM_INTEGER)
175 return 0;
176
177 SET_RETURN_SIZE(p, sizeof(int32_t)); /* Minimum expected size */
178 switch (p->data_size) {
179 case sizeof(int32_t):
180 SET_RETURN_SIZE(p, sizeof(int32_t));
181 *(int32_t *)p->data = val;
182 return 1;
183 case sizeof(int64_t):
184 SET_RETURN_SIZE(p, sizeof(int64_t));
185 *(int64_t *)p->data = (int64_t)val;
186 return 1;
187 }
188 return 0;
189 }
190
191 OSSL_PARAM OSSL_PARAM_construct_int32(const char *key, int32_t *buf,
192 size_t *rsize)
193 {
194 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf,
195 sizeof(int32_t), rsize);
196 }
197
198 int OSSL_PARAM_get_uint32(const OSSL_PARAM *p, uint32_t *val)
199 {
200 if (val == NULL
201 || p == NULL
202 || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
203 return 0;
204
205 if (p->data_size == sizeof(uint32_t)) {
206 *val = *(const uint32_t *)p->data;
207 return 1;
208 }
209 return 0;
210 }
211
212 int OSSL_PARAM_set_uint32(const OSSL_PARAM *p, uint32_t val)
213 {
214 if (p == NULL) return 0;
215 SET_RETURN_SIZE(p, 0);
216 if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
217 return 0;
218
219 SET_RETURN_SIZE(p, sizeof(uint32_t)); /* Minimum expected size */
220 switch (p->data_size) {
221 case sizeof(uint32_t):
222 SET_RETURN_SIZE(p, sizeof(uint32_t));
223 *(uint32_t *)p->data = val;
224 return 1;
225 case sizeof(uint64_t):
226 SET_RETURN_SIZE(p, sizeof(uint64_t));
227 *(uint64_t *)p->data = (uint64_t)val;
228 return 1;
229 }
230 return 0;
231 }
232
233 OSSL_PARAM OSSL_PARAM_construct_uint32(const char *key, uint32_t *buf,
234 size_t *rsize)
235 {
236 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
237 sizeof(uint32_t), rsize);
238 }
239
240 int OSSL_PARAM_get_int64(const OSSL_PARAM *p, int64_t *val)
241 {
242 if (val == NULL || p == NULL || (p->data_type != OSSL_PARAM_INTEGER))
243 return 0;
244
245 switch (p->data_size) {
246 case sizeof(int32_t):
247 *val = (int64_t)*(const int32_t *)p->data;
248 return 1;
249 case sizeof(int64_t):
250 *val = *(const int64_t *)p->data;
251 return 1;
252 }
253 return 0;
254 }
255
256 int OSSL_PARAM_set_int64(const OSSL_PARAM *p, int64_t val)
257 {
258 if (p == NULL)
259 return 0;
260 SET_RETURN_SIZE(p, 0);
261 if (p->data_type != OSSL_PARAM_INTEGER)
262 return 0;
263
264 SET_RETURN_SIZE(p, sizeof(int64_t)); /* Minimum expected size */
265 switch (p->data_size) {
266 case sizeof(int64_t):
267 SET_RETURN_SIZE(p, sizeof(int64_t));
268 *(int64_t *)p->data = val;
269 return 1;
270 }
271 return 0;
272 }
273
274 OSSL_PARAM OSSL_PARAM_construct_int64(const char *key, int64_t *buf,
275 size_t *rsize)
276 {
277 return ossl_param_construct(key, OSSL_PARAM_INTEGER, buf, sizeof(int64_t),
278 rsize);
279 }
280
281 int OSSL_PARAM_get_uint64(const OSSL_PARAM *p, uint64_t *val)
282 {
283 if (val == NULL
284 || p == NULL
285 || (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER))
286 return 0;
287
288 switch (p->data_size) {
289 case sizeof(uint32_t):
290 *val = (uint64_t)*(const uint32_t *)p->data;
291 return 1;
292 case sizeof(uint64_t):
293 *val = *(const uint64_t *)p->data;
294 return 1;
295 }
296 return 0;
297 }
298
299 int OSSL_PARAM_set_uint64(const OSSL_PARAM *p, uint64_t val)
300 {
301 if (p == NULL)
302 return 0;
303 SET_RETURN_SIZE(p, 0);
304 if (p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
305 return 0;
306
307 SET_RETURN_SIZE(p, sizeof(uint64_t)); /* Minimum expected size */
308 switch (p->data_size) {
309 case sizeof(uint64_t):
310 SET_RETURN_SIZE(p, sizeof(uint64_t));
311 *(uint64_t *)p->data = val;
312 return 1;
313 }
314 return 0;
315 }
316
317 OSSL_PARAM OSSL_PARAM_construct_uint64(const char *key, uint64_t *buf,
318 size_t *rsize) {
319 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
320 sizeof(uint64_t), rsize);
321 }
322
323 int OSSL_PARAM_get_size_t(const OSSL_PARAM *p, size_t *val)
324 {
325 switch (sizeof(size_t)) {
326 case sizeof(uint32_t):
327 return OSSL_PARAM_get_uint32(p, (uint32_t *)val);
328 case sizeof(uint64_t):
329 return OSSL_PARAM_get_uint64(p, (uint64_t *)val);
330 }
331 return 0;
332 }
333
334 int OSSL_PARAM_set_size_t(const OSSL_PARAM *p, size_t val)
335 {
336 switch (sizeof(size_t)) {
337 case sizeof(uint32_t):
338 return OSSL_PARAM_set_uint32(p, (uint32_t)val);
339 case sizeof(uint64_t):
340 return OSSL_PARAM_set_uint64(p, (uint64_t)val);
341 }
342 return 0;
343 }
344
345 OSSL_PARAM OSSL_PARAM_construct_size_t(const char *key, size_t *buf,
346 size_t *rsize)
347 {
348 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER, buf,
349 sizeof(size_t), rsize); }
350
351 int OSSL_PARAM_get_BN(const OSSL_PARAM *p, BIGNUM **val)
352 {
353 BIGNUM *b;
354
355 if (val == NULL
356 || p == NULL
357 || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
358 return 0;
359
360 b = BN_native2bn(p->data, (int)p->data_size, *val);
361 if (b != NULL) {
362 *val = b;
363 return 1;
364 }
365 return 0;
366 }
367
368 int OSSL_PARAM_set_BN(const OSSL_PARAM *p, const BIGNUM *val)
369 {
370 size_t bytes;
371
372 if (p == NULL)
373 return 0;
374 SET_RETURN_SIZE(p, 0);
375 if (val == NULL || p->data_type != OSSL_PARAM_UNSIGNED_INTEGER)
376 return 0;
377
378 bytes = (size_t)BN_num_bytes(val);
379 SET_RETURN_SIZE(p, bytes);
380 return p->data_size >= bytes
381 && BN_bn2nativepad(val, p->data, bytes) >= 0;
382 }
383
384 OSSL_PARAM OSSL_PARAM_construct_BN(const char *key, unsigned char *buf,
385 size_t bsize, size_t *rsize)
386 {
387 return ossl_param_construct(key, OSSL_PARAM_UNSIGNED_INTEGER,
388 buf, bsize, rsize);
389 }
390
391 int OSSL_PARAM_get_double(const OSSL_PARAM *p, double *val)
392 {
393 if (val == NULL || p == NULL || p->data_type != OSSL_PARAM_REAL)
394 return 0;
395
396 switch (p->data_size) {
397 case sizeof(double):
398 *val = *(const double *)p->data;
399 return 1;
400 }
401 return 0;
402 }
403
404 int OSSL_PARAM_set_double(const OSSL_PARAM *p, double val)
405 {
406 if (p == NULL)
407 return 0;
408 SET_RETURN_SIZE(p, 0);
409 if (p->data_type != OSSL_PARAM_REAL)
410 return 0;
411
412 switch (p->data_size) {
413 case sizeof(double):
414 SET_RETURN_SIZE(p, sizeof(double));
415 *(double *)p->data = val;
416 return 1;
417 }
418 return 0;
419 }
420
421 OSSL_PARAM OSSL_PARAM_construct_double(const char *key, double *buf,
422 size_t *rsize)
423 {
424 return ossl_param_construct(key, OSSL_PARAM_REAL, buf, sizeof(double),
425 rsize);
426 }
427
428 static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len,
429 size_t *used_len, unsigned int type)
430 {
431 size_t sz;
432
433 if (val == NULL || p == NULL || p->data_type != type)
434 return 0;
435
436 sz = p->data_size;
437
438 if (used_len != NULL)
439 *used_len = sz;
440
441 if (*val == NULL) {
442 char *const q = OPENSSL_malloc(sz);
443
444 if (q == NULL)
445 return 0;
446 *val = q;
447 memcpy(q, p->data, sz);
448 return 1;
449 }
450 if (max_len < sz)
451 return 0;
452 memcpy(*val, p->data, sz);
453 return 1;
454 }
455
456 int OSSL_PARAM_get_utf8_string(const OSSL_PARAM *p, char **val, size_t max_len)
457 {
458 return get_string_internal(p, (void **)val, max_len, NULL,
459 OSSL_PARAM_UTF8_STRING);
460 }
461
462 int OSSL_PARAM_get_octet_string(const OSSL_PARAM *p, void **val, size_t max_len,
463 size_t *used_len)
464 {
465 return get_string_internal(p, val, max_len, used_len,
466 OSSL_PARAM_OCTET_STRING);
467 }
468
469 static int set_string_internal(const OSSL_PARAM *p, const void *val, size_t len,
470 unsigned int type)
471 {
472 SET_RETURN_SIZE(p, len);
473 if (p->data_type != type || p->data_size < len)
474 return 0;
475
476 memcpy(p->data, val, len);
477 return 1;
478 }
479
480 int OSSL_PARAM_set_utf8_string(const OSSL_PARAM *p, const char *val)
481 {
482 if (p == NULL)
483 return 0;
484
485 SET_RETURN_SIZE(p, 0);
486 if (val == NULL)
487 return 0;
488 return set_string_internal(p, val, strlen(val) + 1, OSSL_PARAM_UTF8_STRING);
489 }
490
491 int OSSL_PARAM_set_octet_string(const OSSL_PARAM *p, const void *val,
492 size_t len)
493 {
494 if (p == NULL)
495 return 0;
496
497 SET_RETURN_SIZE(p, 0);
498 if (val == NULL)
499 return 0;
500 return set_string_internal(p, val, len, OSSL_PARAM_OCTET_STRING);
501 }
502
503 OSSL_PARAM OSSL_PARAM_construct_utf8_string(const char *key, char *buf,
504 size_t bsize, size_t *rsize)
505 {
506 return ossl_param_construct(key, OSSL_PARAM_UTF8_STRING, buf, bsize,
507 rsize);
508 }
509
510 OSSL_PARAM OSSL_PARAM_construct_octet_string(const char *key, void *buf,
511 size_t bsize, size_t *rsize)
512 {
513 return ossl_param_construct(key, OSSL_PARAM_OCTET_STRING, buf, bsize,
514 rsize);
515 }
516
517 static int get_ptr_internal(const OSSL_PARAM *p, const void **val,
518 size_t *used_len, unsigned int type)
519 {
520 if (val == NULL || p == NULL || p->data_type != type)
521 return 0;
522 if (used_len != NULL)
523 *used_len = p->data_size;
524 *val = *(const void **)p->data;
525 return 1;
526 }
527
528 int OSSL_PARAM_get_utf8_ptr(const OSSL_PARAM *p, const char **val)
529 {
530 return get_ptr_internal(p, (const void **)val, NULL, OSSL_PARAM_UTF8_PTR);
531 }
532
533 int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val,
534 size_t *used_len)
535 {
536 return get_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_PTR);
537 }
538
539 static int set_ptr_internal(const OSSL_PARAM *p, const void *val,
540 unsigned int type, size_t len)
541 {
542 SET_RETURN_SIZE(p, len);
543 if (p->data_type != type)
544 return 0;
545 *(const void **)p->data = val;
546 return 1;
547 }
548
549 int OSSL_PARAM_set_utf8_ptr(const OSSL_PARAM *p, const char *val)
550 {
551 if (p == NULL)
552 return 0;
553 SET_RETURN_SIZE(p, 0);
554 if (val == NULL)
555 return 0;
556 return set_ptr_internal(p, val, OSSL_PARAM_UTF8_PTR, strlen(val) + 1);
557 }
558
559 int OSSL_PARAM_set_octet_ptr(const OSSL_PARAM *p, const void *val,
560 size_t used_len)
561 {
562 if (p == NULL)
563 return 0;
564 SET_RETURN_SIZE(p, 0);
565 if (val == NULL)
566 return 0;
567 return set_ptr_internal(p, val, OSSL_PARAM_OCTET_PTR, used_len);
568 }
569
570 OSSL_PARAM OSSL_PARAM_construct_utf8_ptr(const char *key, char **buf,
571 size_t *rsize)
572 {
573 return ossl_param_construct(key, OSSL_PARAM_UTF8_PTR, buf, 0, rsize);
574 }
575
576 OSSL_PARAM OSSL_PARAM_construct_octet_ptr(const char *key, void **buf,
577 size_t *rsize)
578 {
579 return ossl_param_construct(key, OSSL_PARAM_OCTET_PTR, buf, 0, rsize);
580 }