a82971602f36f46e0a459cd0b60645ff510dfc0b
[oweals/openssl.git] / providers / implementations / serializers / serializer_ec_param.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_numbers.h>
11 #include <openssl/pem.h>
12 #include <openssl/ec.h>
13 #include <openssl/types.h>
14 #include <openssl/params.h>
15 #include "prov/bio.h"
16 #include "prov/implementations.h"
17 #include "prov/providercommonerr.h"
18 #include "prov/provider_ctx.h"
19 #include "serializer_local.h"
20
21 static OSSL_OP_serializer_newctx_fn ec_param_newctx;
22 static OSSL_OP_serializer_freectx_fn ec_param_freectx;
23 static OSSL_OP_serializer_serialize_data_fn ec_param_der_data;
24 static OSSL_OP_serializer_serialize_object_fn ec_param_der;
25 static OSSL_OP_serializer_serialize_data_fn ec_param_pem_data;
26 static OSSL_OP_serializer_serialize_object_fn ec_param_pem;
27
28 static OSSL_OP_serializer_serialize_data_fn ec_param_print_data;
29 static OSSL_OP_serializer_serialize_object_fn ec_param_print;
30
31
32 /* There is no specific implementation context, so use the provider context */
33 static void *ec_param_newctx(void *provctx)
34 {
35     return provctx;
36 }
37
38 static void ec_param_freectx(void *vctx)
39 {
40 }
41
42 /* Public key : DER */
43 static int ec_param_der_data(void *vctx, const OSSL_PARAM params[],
44                              OSSL_CORE_BIO *out,
45                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
46 {
47     OSSL_OP_keymgmt_new_fn *ec_new;
48     OSSL_OP_keymgmt_free_fn *ec_free;
49     OSSL_OP_keymgmt_import_fn *ec_import;
50     int ok = 0;
51
52     ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
53
54     if (ec_import != NULL) {
55         EC_KEY *eckey;
56
57         /* vctx == provctx */
58         if ((eckey = ec_new(vctx)) != NULL
59             && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
60             && ec_param_der(vctx, eckey, out, cb, cbarg))
61             ok = 1;
62         ec_free(eckey);
63     }
64     return ok;
65 }
66
67 static int ec_param_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
68                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
69 {
70     BIO *out = bio_new_from_core_bio(vctx, cout);
71     int ret;
72
73     if (out == NULL)
74         return 0;
75
76     ret = i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey));
77     BIO_free(out);
78
79     return ret;
80 }
81
82 /* Public key : PEM */
83 static int ec_param_pem_data(void *vctx, const OSSL_PARAM params[],
84                              OSSL_CORE_BIO *out,
85                              OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
86 {
87     OSSL_OP_keymgmt_new_fn *ec_new;
88     OSSL_OP_keymgmt_free_fn *ec_free;
89     OSSL_OP_keymgmt_import_fn *ec_import;
90     int ok = 0;
91
92     ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
93
94     if (ec_import != NULL) {
95         EC_KEY *eckey;
96
97         /* vctx == provctx */
98         if ((eckey = ec_new(vctx)) != NULL
99             && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
100             && ec_param_pem(vctx, eckey, out, cb, cbarg))
101             ok = 1;
102         ec_free(eckey);
103     }
104     return ok;
105 }
106
107 static int ec_param_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
108                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
109 {
110     BIO *out = bio_new_from_core_bio(vctx, cout);
111     int ret;
112
113     if (out == NULL)
114         return 0;
115
116     ret = PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey));
117     BIO_free(out);
118
119     return ret;
120 }
121
122 static int ec_param_print_data(void *vctx, const OSSL_PARAM params[],
123                                OSSL_CORE_BIO *out,
124                                OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
125 {
126     OSSL_OP_keymgmt_new_fn *ec_new;
127     OSSL_OP_keymgmt_free_fn *ec_free;
128     OSSL_OP_keymgmt_import_fn *ec_import;
129     int ok = 0;
130
131     ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
132
133     if (ec_import != NULL) {
134         EC_KEY *eckey;
135
136         /* vctx == provctx */
137         if ((eckey = ec_new(vctx)) != NULL
138             && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
139             && ec_param_print(vctx, eckey, out, cb, cbarg))
140             ok = 1;
141         ec_free(eckey);
142     }
143     return ok;
144 }
145
146 static int ec_param_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
147                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
148 {
149     BIO *out = bio_new_from_core_bio(vctx, cout);
150     int ret;
151
152     if (out == NULL)
153         return 0;
154
155     ret = ossl_prov_print_eckey(out, eckey, ec_print_params);
156     BIO_free(out);
157
158     return ret;
159 }
160
161 const OSSL_DISPATCH ec_param_der_serializer_functions[] = {
162     { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
163     { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
164     { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_der_data },
165     { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_der },
166     { 0, NULL }
167 };
168
169 const OSSL_DISPATCH ec_param_pem_serializer_functions[] = {
170     { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
171     { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
172     { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_pem_data },
173     { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_pem },
174     { 0, NULL }
175 };
176
177 const OSSL_DISPATCH ec_param_text_serializer_functions[] = {
178     { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
179     { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
180     { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_print },
181     { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
182       (void (*)(void))ec_param_print_data },
183     { 0, NULL }
184 };