Make the naming scheme for dispatched functions more consistent
[oweals/openssl.git] / providers / implementations / serializers / serializer_ecx_pub.c
1 /*
2  * Copyright 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 <openssl/core_dispatch.h>
11 #include <openssl/err.h>
12 #include <openssl/pem.h>
13 #include <openssl/types.h>
14 #include <openssl/params.h>
15 #include "crypto/ecx.h"
16 #include "prov/bio.h"
17 #include "prov/implementations.h"
18 #include "prov/provider_ctx.h"
19 #include "serializer_local.h"
20
21 static OSSL_FUNC_serializer_newctx_fn x25519_pub_newctx;
22 static OSSL_FUNC_serializer_newctx_fn x448_pub_newctx;
23 static OSSL_FUNC_serializer_newctx_fn ed25519_pub_newctx;
24 static OSSL_FUNC_serializer_newctx_fn ed448_pub_newctx;
25 static OSSL_FUNC_serializer_freectx_fn ecx_pub_freectx;
26 static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_der_data;
27 static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_der;
28 static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_pem_data;
29 static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_pem;
30
31 static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_print_data;
32 static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_print;
33
34 /*
35  * Context used for public key serialization.
36  */
37 struct ecx_pub_ctx_st {
38     void *provctx;
39     ECX_KEY_TYPE type;
40 };
41
42 /* Public key : context */
43 static void *ecx_pub_newctx(void *provctx, ECX_KEY_TYPE type)
44 {
45     struct ecx_pub_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
46
47     if (ctx != NULL) {
48         ctx->provctx = provctx;
49         ctx->type = type;
50     }
51     return ctx;
52 }
53
54 static void *x25519_pub_newctx(void *provctx)
55 {
56     return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X25519);
57 }
58
59 static void *x448_pub_newctx(void *provctx)
60 {
61     return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X448);
62 }
63
64 static void *ed25519_pub_newctx(void *provctx)
65 {
66     return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED25519);
67 }
68
69 static void *ed448_pub_newctx(void *provctx)
70 {
71     return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED448);
72 }
73
74 static void ecx_pub_freectx(void *ctx)
75 {
76     OPENSSL_free(ctx);
77 }
78
79 /* Public key : DER */
80 static int ecx_pub_der_data(void *vctx, const OSSL_PARAM params[],
81                             OSSL_CORE_BIO *out,
82                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
83 {
84     struct ecx_pub_ctx_st *ctx = vctx;
85     OSSL_FUNC_keymgmt_new_fn *ecx_new;
86     OSSL_FUNC_keymgmt_free_fn *ecx_free;
87     OSSL_FUNC_keymgmt_import_fn *ecx_import;
88     int ok = 0;
89
90     ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
91
92     if (ecx_import != NULL) {
93         ECX_KEY *ecxkey;
94
95         if ((ecxkey = ecx_new(ctx->provctx)) != NULL
96             && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
97             && ecx_pub_der(ctx, ecxkey, out, cb, cbarg))
98             ok = 1;
99         ecx_free(ecxkey);
100     }
101     return ok;
102 }
103
104 static int ecx_pub_der(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
105                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
106 {
107     struct ecx_pub_ctx_st *ctx = vctx;
108     BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
109     int ret;
110
111     if (out == NULL)
112         return 0;
113
114     ret = ossl_prov_write_pub_der_from_obj(out, ecxkey,
115                                            KEYTYPE2NID(ctx->type),
116                                            NULL,
117                                            ossl_prov_ecx_pub_to_der);
118     BIO_free(out);
119
120     return ret;
121 }
122
123 /* Public key : PEM */
124 static int ecx_pub_pem_data(void *vctx, const OSSL_PARAM params[],
125                             OSSL_CORE_BIO *out,
126                             OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
127 {
128     struct ecx_pub_ctx_st *ctx = vctx;
129     OSSL_FUNC_keymgmt_new_fn *ecx_new;
130     OSSL_FUNC_keymgmt_free_fn *ecx_free;
131     OSSL_FUNC_keymgmt_import_fn *ecx_import;
132     int ok = 0;
133
134     ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
135
136     if (ecx_import != NULL) {
137         ECX_KEY *ecxkey;
138
139         if ((ecxkey = ecx_new(ctx->provctx)) != NULL
140             && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
141             && ecx_pub_pem(ctx, ecxkey, out, cb, cbarg))
142             ok = 1;
143         ecx_free(ecxkey);
144     }
145     return ok;
146 }
147
148 static int ecx_pub_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
149                        OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
150 {
151     struct ecx_pub_ctx_st *ctx = vctx;
152     BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
153     int ret;
154
155     if (out == NULL)
156         return 0;
157
158     ret = ossl_prov_write_pub_pem_from_obj(out, ecxkey,
159                                            KEYTYPE2NID(ctx->type),
160                                            NULL,
161                                            ossl_prov_ecx_pub_to_der);
162     BIO_free(out);
163
164     return ret;
165 }
166
167 static int ecx_pub_print_data(void *vctx, const OSSL_PARAM params[],
168                               OSSL_CORE_BIO *out,
169                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
170 {
171     struct ecx_pub_ctx_st *ctx = vctx;
172     OSSL_FUNC_keymgmt_new_fn *ecx_new;
173     OSSL_FUNC_keymgmt_free_fn *ecx_free;
174     OSSL_FUNC_keymgmt_import_fn *ecx_import;
175     int ok = 0;
176
177     ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
178
179     if (ecx_import != NULL) {
180         ECX_KEY *ecxkey;
181
182         if ((ecxkey = ecx_new(ctx)) != NULL
183             && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
184             && ecx_pub_print(ctx, ecxkey, out, cb, cbarg))
185             ok = 1;
186         ecx_free(ecxkey);
187     }
188     return ok;
189 }
190
191 static int ecx_pub_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
192                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
193 {
194     struct ecx_pub_ctx_st *ctx = vctx;
195     BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
196     int ret;
197
198     if (out == NULL)
199         return 0;
200
201     ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_pub);
202     BIO_free(out);
203
204     return ret;
205 }
206
207 #define MAKE_SERIALIZER_FUNCTIONS(alg, type) \
208     const OSSL_DISPATCH alg##_pub_##type##_serializer_functions[] = { \
209         { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_pub_newctx }, \
210         { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_pub_freectx }, \
211         { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \
212           (void (*)(void))ecx_pub_##type##_data }, \
213         { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \
214           (void (*)(void))ecx_pub_##type }, \
215         { 0, NULL } \
216     };
217
218 #define MAKE_SERIALIZER_FUNCTIONS_GROUP(alg) \
219     MAKE_SERIALIZER_FUNCTIONS(alg, der) \
220     MAKE_SERIALIZER_FUNCTIONS(alg, pem) \
221     MAKE_SERIALIZER_FUNCTIONS(alg, print)
222
223 MAKE_SERIALIZER_FUNCTIONS_GROUP(x25519)
224 MAKE_SERIALIZER_FUNCTIONS_GROUP(x448)
225 MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519)
226 MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448)