1 /*
2 * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/core_dispatch.h>
11 #include <openssl/core_names.h>
12 #include <openssl/params.h>
13 #include <openssl/err.h>
14 #include <openssl/proverr.h>
15 #include <openssl/evp.h>
16 #include <openssl/rand.h>
17 #include <openssl/self_test.h>
18 #include "internal/param_build_set.h"
19 #include <openssl/param_build.h>
20 #include "prov/implementations.h"
21 #include "prov/providercommon.h"
22 #include "prov/provider_ctx.h"
23 #include "prov/securitycheck.h"
24
25 extern const OSSL_DISPATCH ossl_template_keymgmt_functions[];
26
27 #define BUFSIZE 1000
28 #if defined(NDEBUG) || defined(OPENSSL_NO_STDIO)
debug_print(char * fmt,...)29 static void debug_print(char *fmt, ...)
30 {
31 }
32 #else
debug_print(char * fmt,...)33 static void debug_print(char *fmt, ...)
34 {
35 char out[BUFSIZE];
36 va_list argptr;
37
38 va_start(argptr, fmt);
39 vsnprintf(out, BUFSIZE, fmt, argptr);
40 va_end(argptr);
41 if (getenv("TEMPLATEKM"))
42 fprintf(stderr, "TEMPLATE_KM: %s", out);
43 }
44 #endif
45
46 static OSSL_FUNC_keymgmt_new_fn template_new;
47 static OSSL_FUNC_keymgmt_free_fn template_free;
48 static OSSL_FUNC_keymgmt_gen_init_fn template_gen_init;
49 static OSSL_FUNC_keymgmt_gen_fn template_gen;
50 static OSSL_FUNC_keymgmt_gen_cleanup_fn template_gen_cleanup;
51 static OSSL_FUNC_keymgmt_gen_set_params_fn template_gen_set_params;
52 static OSSL_FUNC_keymgmt_gen_settable_params_fn template_gen_settable_params;
53 static OSSL_FUNC_keymgmt_get_params_fn template_get_params;
54 static OSSL_FUNC_keymgmt_gettable_params_fn template_gettable_params;
55 static OSSL_FUNC_keymgmt_set_params_fn template_set_params;
56 static OSSL_FUNC_keymgmt_settable_params_fn template_settable_params;
57 static OSSL_FUNC_keymgmt_has_fn template_has;
58 static OSSL_FUNC_keymgmt_match_fn template_match;
59 static OSSL_FUNC_keymgmt_import_fn template_import;
60 static OSSL_FUNC_keymgmt_export_fn template_export;
61 static OSSL_FUNC_keymgmt_import_types_fn template_imexport_types;
62 static OSSL_FUNC_keymgmt_export_types_fn template_imexport_types;
63
64 static OSSL_FUNC_keymgmt_dup_fn template_dup;
65
66 struct template_gen_ctx {
67 void *provctx;
68 int selection;
69 };
70
template_new(void * provctx)71 static void *template_new(void *provctx)
72 {
73 void *key = NULL;
74
75 debug_print("new key req\n");
76 if (!ossl_prov_is_running())
77 return 0;
78
79 /* add logic to create new key */
80
81 debug_print("new key = %p\n", key);
82 return key;
83 }
84
template_free(void * vkey)85 static void template_free(void *vkey)
86 {
87 debug_print("free key %p\n", vkey);
88 if (vkey == NULL)
89 return;
90
91 /* add logic to free all key components */
92
93 OPENSSL_free(vkey);
94 }
95
template_has(const void * keydata,int selection)96 static int template_has(const void *keydata, int selection)
97 {
98 int ok = 0;
99
100 debug_print("has %p\n", keydata);
101 if (ossl_prov_is_running() && keydata != NULL) {
102 /* add logic to check whether this key has the requested parameters */
103 }
104 debug_print("has result %d\n", ok);
105 return ok;
106 }
107
template_match(const void * keydata1,const void * keydata2,int selection)108 static int template_match(const void *keydata1, const void *keydata2, int selection)
109 {
110 int ok = 1;
111
112 debug_print("matching %p and %p\n", keydata1, keydata2);
113 if (!ossl_prov_is_running())
114 return 0;
115
116 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
117 ok = ok && keydata1 != NULL && keydata2 != NULL;
118
119 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
120 int key_checked = 0;
121
122 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
123 /* validate whether the public keys match */
124 }
125 if (!key_checked
126 && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
127 /* validate whether the private keys match */
128 }
129 ok = ok && key_checked;
130 }
131 debug_print("match result %d\n", ok);
132 return ok;
133 }
134
key_to_params(void * key,OSSL_PARAM_BLD * tmpl,OSSL_PARAM params[],int include_private)135 static int key_to_params(void *key, OSSL_PARAM_BLD *tmpl,
136 OSSL_PARAM params[], int include_private)
137 {
138 if (key == NULL)
139 return 0;
140
141 /* add public and/or private key parts to templ as possible */
142
143 return 1;
144 }
145
template_export(void * key,int selection,OSSL_CALLBACK * param_cb,void * cbarg)146 static int template_export(void *key, int selection, OSSL_CALLBACK *param_cb,
147 void *cbarg)
148 {
149 OSSL_PARAM_BLD *tmpl;
150 OSSL_PARAM *params = NULL;
151 int ret = 0;
152
153 debug_print("export %p\n", key);
154 if (!ossl_prov_is_running() || key == NULL)
155 return 0;
156
157 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
158 return 0;
159
160 tmpl = OSSL_PARAM_BLD_new();
161 if (tmpl == NULL)
162 return 0;
163
164 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
165 int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
166
167 if (!key_to_params(key, tmpl, NULL, include_private))
168 goto err;
169 }
170
171 params = OSSL_PARAM_BLD_to_param(tmpl);
172 if (params == NULL)
173 goto err;
174
175 ret = param_cb(params, cbarg);
176 OSSL_PARAM_free(params);
177 err:
178 OSSL_PARAM_BLD_free(tmpl);
179 debug_print("export result %d\n", ret);
180 return ret;
181 }
182
ossl_template_key_fromdata(void * key,const OSSL_PARAM params[],int include_private)183 static int ossl_template_key_fromdata(void *key,
184 const OSSL_PARAM params[],
185 int include_private)
186 {
187 const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
188
189 if (key == NULL)
190 return 0;
191 if (ossl_param_is_empty(params))
192 return 0;
193
194 /* validate integrity of key (algorithm type specific) */
195
196 param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
197 if (include_private)
198 param_priv_key =
199 OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
200
201 if (param_pub_key == NULL && param_priv_key == NULL)
202 return 0;
203
204 if (param_priv_key != NULL) {
205 /* retrieve private key and check integrity */
206 }
207
208 if (param_pub_key != NULL) {
209 /* retrieve public key and check integrity */
210 }
211
212 return 1;
213 }
214
template_import(void * key,int selection,const OSSL_PARAM params[])215 static int template_import(void *key, int selection, const OSSL_PARAM params[])
216 {
217 int ok = 1;
218 int include_private;
219
220 debug_print("import %p\n", key);
221 if (!ossl_prov_is_running() || key == NULL)
222 return 0;
223
224 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
225 return 0;
226
227 include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
228 ok = ok && ossl_template_key_fromdata(key, params, include_private);
229
230 debug_print("import result %d\n", ok);
231 return ok;
232 }
233
234 #define TEMPLATE_KEY_TYPES() \
235 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
236 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
237
238 static const OSSL_PARAM template_key_types[] = {
239 TEMPLATE_KEY_TYPES(),
240 OSSL_PARAM_END
241 };
242
template_imexport_types(int selection)243 static const OSSL_PARAM *template_imexport_types(int selection)
244 {
245 debug_print("getting imexport types\n");
246 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
247 return template_key_types;
248 return NULL;
249 }
250
template_get_params(void * key,OSSL_PARAM params[])251 static int template_get_params(void *key, OSSL_PARAM params[])
252 {
253 OSSL_PARAM *p;
254
255 debug_print("get params %p\n", key);
256
257 if (ossl_param_is_empty(params))
258 return 0;
259
260 /* return sensible values for at least these parameters */
261
262 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
263 && !OSSL_PARAM_set_int(p, 0))
264 return 0;
265 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
266 && !OSSL_PARAM_set_int(p, 0))
267 return 0;
268 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
269 && !OSSL_PARAM_set_int(p, 0))
270 return 0;
271 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {
272 if (!OSSL_PARAM_set_octet_string(p, NULL, 0))
273 return 0;
274 }
275
276 debug_print("get params OK\n");
277 return 1;
278 }
279
280 static const OSSL_PARAM template_gettable_params_arr[] = {
281 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
282 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
283 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
284 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
285 OSSL_PARAM_END
286 };
287
template_gettable_params(void * provctx)288 static const OSSL_PARAM *template_gettable_params(void *provctx)
289 {
290 debug_print("gettable params called\n");
291 return template_gettable_params_arr;
292 }
293
template_set_params(void * key,const OSSL_PARAM params[])294 static int template_set_params(void *key, const OSSL_PARAM params[])
295 {
296 const OSSL_PARAM *p;
297
298 debug_print("set params called for %p\n", key);
299 if (ossl_param_is_empty(params))
300 return 1; /* OK not to set anything */
301
302 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
303 if (p != NULL) {
304 /* load public key structure */
305 }
306
307 debug_print("set params OK\n");
308 return 1;
309 }
310
311 static const OSSL_PARAM template_settable_params_arr[] = {
312 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
313 OSSL_PARAM_END
314 };
315
template_settable_params(void * provctx)316 static const OSSL_PARAM *template_settable_params(void *provctx)
317 {
318 debug_print("settable params called\n");
319 return template_settable_params_arr;
320 }
321
template_gen_set_params(void * genctx,const OSSL_PARAM params[])322 static int template_gen_set_params(void *genctx, const OSSL_PARAM params[])
323 {
324 struct template_gen_ctx *gctx = genctx;
325
326 if (gctx == NULL)
327 return 0;
328
329 debug_print("empty gen_set params called for %p\n", gctx);
330 return 1;
331 }
332
template_gen_init(void * provctx,int selection,const OSSL_PARAM params[])333 static void *template_gen_init(void *provctx, int selection,
334 const OSSL_PARAM params[])
335 {
336 struct template_gen_ctx *gctx = NULL;
337
338 debug_print("gen init called for %p\n", provctx);
339
340 /* perform algorithm type specific sanity checks */
341
342 if (!ossl_prov_is_running())
343 return NULL;
344
345 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
346 gctx->provctx = provctx;
347 gctx->selection = selection;
348 }
349 if (!template_gen_set_params(gctx, params)) {
350 OPENSSL_free(gctx);
351 gctx = NULL;
352 }
353 debug_print("gen init returns %p\n", gctx);
354 return gctx;
355 }
356
template_gen_settable_params(ossl_unused void * genctx,ossl_unused void * provctx)357 static const OSSL_PARAM *template_gen_settable_params(ossl_unused void *genctx,
358 ossl_unused void *provctx)
359 {
360 static OSSL_PARAM settable[] = {
361 OSSL_PARAM_END
362 };
363 return settable;
364 }
365
template_gen(void * vctx,OSSL_CALLBACK * osslcb,void * cbarg)366 static void *template_gen(void *vctx, OSSL_CALLBACK *osslcb, void *cbarg)
367 {
368 struct template_gen_ctx *gctx = (struct template_gen_ctx *)vctx;
369 void *key = NULL;
370
371 debug_print("gen called for %p\n", gctx);
372
373 if (gctx == NULL)
374 goto err;
375
376 /* generate and return new key */
377
378 debug_print("gen returns set %p\n", key);
379 return key;
380 err:
381 template_free(key);
382 debug_print("gen returns NULL\n");
383 return NULL;
384 }
385
template_gen_cleanup(void * genctx)386 static void template_gen_cleanup(void *genctx)
387 {
388 struct template_gen_ctx *gctx = genctx;
389
390 debug_print("gen cleanup for %p\n", gctx);
391 OPENSSL_free(gctx);
392 }
393
template_dup(const void * vsrckey,int selection)394 static void *template_dup(const void *vsrckey, int selection)
395 {
396 void *dstkey = NULL;
397
398 debug_print("dup called for %p\n", vsrckey);
399 if (!ossl_prov_is_running())
400 return NULL;
401
402 dstkey = template_new(NULL);
403 if (dstkey == NULL)
404 goto err;
405
406 /* populate dstkey from vsrckey material */
407
408 debug_print("dup returns %p\n", dstkey);
409 return dstkey;
410 err:
411 template_free(dstkey);
412 debug_print("dup returns NULL\n");
413 return NULL;
414 }
415
416 const OSSL_DISPATCH ossl_template_keymgmt_functions[] = {
417 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))template_new },
418 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))template_free },
419 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))template_get_params },
420 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))template_gettable_params },
421 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))template_set_params },
422 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))template_settable_params },
423 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))template_has },
424 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))template_match },
425 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))template_imexport_types },
426 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))template_imexport_types },
427 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))template_import },
428 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))template_export },
429 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))template_gen_init },
430 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))template_gen_set_params },
431 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
432 (void (*)(void))template_gen_settable_params },
433 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))template_gen },
434 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))template_gen_cleanup },
435 { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))template_dup },
436 OSSL_DISPATCH_END
437 };
438