4025d9ee168d185d68212c20b9fac06a024570e0
[oweals/openssl.git] / test / tls-provider.c
1 /*
2  * Copyright 2019-2020 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 <string.h>
11 #include <openssl/core_names.h>
12 #include <openssl/core_numbers.h>
13 #include <openssl/rand.h>
14 #include <openssl/params.h>
15 /* For TLS1_3_VERSION */
16 #include <openssl/ssl.h>
17
18 int tls_provider_init(const OSSL_CORE_HANDLE *handle,
19                       const OSSL_DISPATCH *in,
20                       const OSSL_DISPATCH **out,
21                       void **provctx);
22
23 #define XOR_KEY_SIZE 32
24
25 /*
26  * Top secret. This algorithm only works if no one knows what this number is.
27  * Please don't tell anyone what it is.
28  * 
29  * This algorithm is for testing only - don't really use it!
30  */
31 static const unsigned char private_constant[XOR_KEY_SIZE] = {
32     0xd3, 0x6b, 0x54, 0xec, 0x5b, 0xac, 0x89, 0x96, 0x8c, 0x2c, 0x66, 0xa5,
33     0x67, 0x0d, 0xe3, 0xdd, 0x43, 0x69, 0xbc, 0x83, 0x3d, 0x60, 0xc7, 0xb8,
34     0x2b, 0x1c, 0x5a, 0xfd, 0xb5, 0xcd, 0xd0, 0xf8
35 };
36
37 typedef struct xorkey_st {
38     unsigned char privkey[XOR_KEY_SIZE];
39     unsigned char pubkey[XOR_KEY_SIZE];
40     int hasprivkey;
41     int haspubkey;
42 } XORKEY;
43
44 /* We define a dummy TLS group called "xorgroup" for test purposes */
45
46 static unsigned int group_id = 0; /* IANA reserved for private use */
47 static unsigned int secbits = 128;
48 static unsigned int mintls = TLS1_3_VERSION;
49 static unsigned int maxtls = 0;
50 static unsigned int mindtls = -1;
51 static unsigned int maxdtls = -1;
52
53 #define GROUP_NAME "xorgroup"
54 #define GROUP_NAME_INTERNAL "xorgroup-int"
55 #define ALGORITHM "XOR"
56
57 static const OSSL_PARAM xor_group_params[] = {
58     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME,
59                            GROUP_NAME, sizeof(GROUP_NAME)),
60     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL,
61                            GROUP_NAME_INTERNAL, sizeof(GROUP_NAME_INTERNAL)),
62     OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, ALGORITHM,
63                            sizeof(ALGORITHM)),
64     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, &group_id),
65     OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, &secbits),
66     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, &mintls),
67     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, &maxtls),
68     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, &mindtls),
69     OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, &maxdtls),
70     OSSL_PARAM_END
71 };
72
73 static int tls_prov_get_capabilities(void *provctx, const char *capability,
74                                      OSSL_CALLBACK *cb, void *arg)
75 {
76     /* We're only adding one group so we only call the callback once */
77     if (strcmp(capability, "TLS-GROUP") == 0)
78         return cb(xor_group_params, arg);
79
80     /* We don't support this capability */
81     return 0;
82 }
83
84 /*
85  * Dummy "XOR" Key Exchange algorithm. We just xor the private and public keys
86  * together. Don't use this!
87  */
88
89 static OSSL_OP_keyexch_newctx_fn xor_newctx;
90 static OSSL_OP_keyexch_init_fn xor_init;
91 static OSSL_OP_keyexch_set_peer_fn xor_set_peer;
92 static OSSL_OP_keyexch_derive_fn xor_derive;
93 static OSSL_OP_keyexch_freectx_fn xor_freectx;
94 static OSSL_OP_keyexch_dupctx_fn xor_dupctx;
95
96 typedef struct {
97     XORKEY *key;
98     XORKEY *peerkey;
99 } PROV_XOR_CTX;
100
101 static void *xor_newctx(void *provctx)
102 {
103     PROV_XOR_CTX *pxorctx = OPENSSL_zalloc(sizeof(PROV_XOR_CTX));
104
105     if (pxorctx == NULL)
106         return NULL;
107
108     return pxorctx;
109 }
110
111 static int xor_init(void *vpxorctx, void *vkey)
112 {
113     PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx;
114
115     if (pxorctx == NULL || vkey == NULL)
116         return 0;
117     pxorctx->key = vkey;
118     return 1;
119 }
120
121 static int xor_set_peer(void *vpxorctx, void *vpeerkey)
122 {
123     PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx;
124
125     if (pxorctx == NULL || vpeerkey == NULL)
126         return 0;
127     pxorctx->peerkey = vpeerkey;
128     return 1;
129 }
130
131 static int xor_derive(void *vpxorctx, unsigned char *secret, size_t *secretlen,
132                       size_t outlen)
133 {
134     PROV_XOR_CTX *pxorctx = (PROV_XOR_CTX *)vpxorctx;
135     int i;
136
137     if (pxorctx->key == NULL || pxorctx->peerkey == NULL)
138         return 0;
139
140     *secretlen = XOR_KEY_SIZE;
141     if (secret == NULL)
142         return 1;
143
144     if (outlen < XOR_KEY_SIZE)
145         return 0;
146
147     for (i = 0; i < XOR_KEY_SIZE; i++)
148         secret[i] = pxorctx->key->privkey[i] ^ pxorctx->peerkey->pubkey[i];
149
150     return 1;
151 }
152
153 static void xor_freectx(void *pxorctx)
154 {
155     OPENSSL_free(pxorctx);
156 }
157
158 static void *xor_dupctx(void *vpxorctx)
159 {
160     PROV_XOR_CTX *srcctx = (PROV_XOR_CTX *)vpxorctx;
161     PROV_XOR_CTX *dstctx;
162
163     dstctx = OPENSSL_zalloc(sizeof(*srcctx));
164     if (dstctx == NULL)
165         return NULL;
166
167     *dstctx = *srcctx;
168
169     return dstctx;
170 }
171
172 static const OSSL_DISPATCH xor_keyexch_functions[] = {
173     { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))xor_newctx },
174     { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))xor_init },
175     { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))xor_derive },
176     { OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))xor_set_peer },
177     { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))xor_freectx },
178     { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))xor_dupctx },
179     { 0, NULL }
180 };
181
182 static const OSSL_ALGORITHM tls_prov_keyexch[] = {
183     { "XOR", "provider=tls-provider", xor_keyexch_functions },
184     { NULL, NULL, NULL }
185 };
186
187 /* Key Management for the dummy XOR key exchange algorithm */
188
189 static OSSL_OP_keymgmt_new_fn xor_newdata;
190 static OSSL_OP_keymgmt_free_fn xor_freedata;
191 static OSSL_OP_keymgmt_has_fn xor_has;
192 static OSSL_OP_keymgmt_copy_fn xor_copy;
193 static OSSL_OP_keymgmt_gen_init_fn xor_gen_init;
194 static OSSL_OP_keymgmt_gen_set_params_fn xor_gen_set_params;
195 static OSSL_OP_keymgmt_gen_settable_params_fn xor_gen_settable_params;
196 static OSSL_OP_keymgmt_gen_fn xor_gen;
197 static OSSL_OP_keymgmt_gen_cleanup_fn xor_gen_cleanup;
198 static OSSL_OP_keymgmt_get_params_fn xor_get_params;
199 static OSSL_OP_keymgmt_gettable_params_fn xor_gettable_params;
200 static OSSL_OP_keymgmt_set_params_fn xor_set_params;
201 static OSSL_OP_keymgmt_settable_params_fn xor_settable_params;
202
203 static void *xor_newdata(void *provctx)
204 {
205     return OPENSSL_zalloc(sizeof(XORKEY));
206 }
207
208 static void xor_freedata(void *keydata)
209 {
210     OPENSSL_free(keydata);
211 }
212
213 static int xor_has(void *vkey, int selection)
214 {
215     XORKEY *key = vkey;
216     int ok = 0;
217
218     if (key != NULL) {
219         ok = 1;
220
221         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
222             ok = ok && key->haspubkey;
223         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
224             ok = ok && key->hasprivkey;
225     }
226     return ok;
227 }
228
229 static int xor_copy(void *vtokey, const void *vfromkey, int selection)
230 {
231     XORKEY *tokey = vtokey;
232     const XORKEY *fromkey = vfromkey;
233     int ok = 0;
234
235     if (tokey != NULL && fromkey != NULL) {
236         ok = 1;
237
238         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
239             if (fromkey->haspubkey) {
240                 memcpy(tokey->pubkey, fromkey->pubkey, XOR_KEY_SIZE);
241                 tokey->haspubkey = 1;
242             } else {
243                 tokey->haspubkey = 0;
244             }
245         }
246         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
247             if (fromkey->hasprivkey) {
248                 memcpy(tokey->privkey, fromkey->privkey, XOR_KEY_SIZE);
249                 tokey->hasprivkey = 1;
250             } else {
251                 tokey->hasprivkey = 0;
252             }
253         }
254     }
255     return ok;
256 }
257
258 static ossl_inline int xor_get_params(void *vkey, OSSL_PARAM params[])
259 {
260     XORKEY *key = vkey;
261     OSSL_PARAM *p;
262
263     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
264         && !OSSL_PARAM_set_int(p, XOR_KEY_SIZE))
265         return 0;
266
267     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
268         && !OSSL_PARAM_set_int(p, secbits))
269         return 0;
270
271     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) {
272         if (p->data_type != OSSL_PARAM_OCTET_STRING)
273             return 0;
274         p->return_size = XOR_KEY_SIZE;
275         if (p->data != NULL && p->data_size >= XOR_KEY_SIZE)
276             memcpy(p->data, key->pubkey, XOR_KEY_SIZE);
277     }
278
279     return 1;
280 }
281
282 static const OSSL_PARAM xor_params[] = {
283     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
284     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
285     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
286     OSSL_PARAM_END
287 };
288
289 static const OSSL_PARAM *xor_gettable_params(void)
290 {
291     return xor_params;
292 }
293
294 static int xor_set_params(void *vkey, const OSSL_PARAM params[])
295 {
296     XORKEY *key = vkey;
297     const OSSL_PARAM *p;
298
299     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
300     if (p != NULL) {
301         if (p->data_type != OSSL_PARAM_OCTET_STRING
302                 || p->data_size != XOR_KEY_SIZE)
303             return 0;
304         memcpy(key->pubkey, p->data, XOR_KEY_SIZE);
305         key->haspubkey = 1;
306     }
307
308     return 1;
309 }
310
311 static const OSSL_PARAM xor_known_settable_params[] = {
312     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
313     OSSL_PARAM_END
314 };
315
316 static const OSSL_PARAM *xor_settable_params(void)
317 {
318     return xor_known_settable_params;
319 }
320
321 struct xor_gen_ctx {
322     int selection;
323     OPENSSL_CTX *libctx;
324 };
325
326 static void *xor_gen_init(void *provctx, int selection)
327 {
328     struct xor_gen_ctx *gctx = NULL;
329
330     if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR
331                       | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0)
332         return NULL;
333
334     if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL)
335         gctx->selection = selection;
336
337     /* Our provctx is really just an OPENSSL_CTX */
338     gctx->libctx = (OPENSSL_CTX *)provctx;
339
340     return gctx;
341 }
342
343 static int xor_gen_set_params(void *genctx, const OSSL_PARAM params[])
344 {
345     struct xor_gen_ctx *gctx = genctx;
346     const OSSL_PARAM *p;
347
348     if (gctx == NULL)
349         return 0;
350
351     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
352     if (p != NULL) {
353         if (p->data_type != OSSL_PARAM_UTF8_STRING
354                 || strcmp(p->data, GROUP_NAME_INTERNAL) != 0)
355             return 0;
356     }
357
358     return 1;
359 }
360
361 static const OSSL_PARAM *xor_gen_settable_params(void *provctx)
362 {
363     static OSSL_PARAM settable[] = {
364         OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
365         OSSL_PARAM_END
366     };
367     return settable;
368 }
369
370 static void *xor_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
371 {
372     struct xor_gen_ctx *gctx = genctx;
373     XORKEY *key = OPENSSL_zalloc(sizeof(*key));
374     size_t i;
375
376     if (key == NULL)
377         return NULL;
378
379     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
380         if (RAND_bytes_ex(gctx->libctx, key->privkey, XOR_KEY_SIZE) <= 0) {
381             OPENSSL_free(key);
382             return NULL;
383         }
384         for (i = 0; i < XOR_KEY_SIZE; i++)
385             key->pubkey[i] = key->privkey[i] ^ private_constant[i];
386         key->hasprivkey = 1;
387         key->haspubkey = 1;
388     }
389
390     return key;
391 }
392
393 static void xor_gen_cleanup(void *genctx)
394 {
395     OPENSSL_free(genctx);
396 }
397
398 static const OSSL_DISPATCH xor_keymgmt_functions[] = {
399     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))xor_newdata },
400     { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))xor_gen_init },
401     { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))xor_gen_set_params },
402     { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,
403       (void (*)(void))xor_gen_settable_params },
404     { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))xor_gen },
405     { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))xor_gen_cleanup },
406     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))xor_get_params },
407     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))xor_gettable_params },
408     { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))xor_set_params },
409     { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))xor_settable_params },
410     { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))xor_has },
411     { OSSL_FUNC_KEYMGMT_COPY, (void (*)(void))xor_copy },
412     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))xor_freedata },
413     { 0, NULL }
414 };
415
416 static const OSSL_ALGORITHM tls_prov_keymgmt[] = {
417     { "XOR", "provider=tls-provider", xor_keymgmt_functions },
418     { NULL, NULL, NULL }
419 };
420
421 static const OSSL_ALGORITHM *tls_prov_query(void *provctx, int operation_id,
422                                             int *no_cache)
423 {
424     *no_cache = 0;
425     switch (operation_id) {
426     case OSSL_OP_KEYMGMT:
427         return tls_prov_keymgmt;
428     case OSSL_OP_KEYEXCH:
429         return tls_prov_keyexch;
430     }
431     return NULL;
432 }
433
434 /* Functions we provide to the core */
435 static const OSSL_DISPATCH tls_prov_dispatch_table[] = {
436     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OPENSSL_CTX_free },
437     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))tls_prov_query },
438     { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))tls_prov_get_capabilities },
439     { 0, NULL }
440 };
441
442 int tls_provider_init(const OSSL_CORE_HANDLE *handle,
443                       const OSSL_DISPATCH *in,
444                       const OSSL_DISPATCH **out,
445                       void **provctx)
446 {
447     OPENSSL_CTX *libctx = OPENSSL_CTX_new();
448
449     *provctx = libctx;
450
451     /*
452      * Randomise the group_id we're going to use to ensure we don't interoperate
453      * with anything but ourselves.
454      */
455     if (!RAND_bytes_ex(libctx, (unsigned char *)&group_id, sizeof(group_id)))
456         return 0;
457     /*
458      * Ensure group_id is within the IANA Reserved for private use range
459      * (65024-65279)
460      */
461     group_id %= 65279 - 65024;
462     group_id += 65024;
463
464     *out = tls_prov_dispatch_table;
465     return 1;
466 }