Add Serializers for EC
[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 "serializer_local.h"
19
20 static OSSL_OP_serializer_newctx_fn ec_param_newctx;
21 static OSSL_OP_serializer_freectx_fn ec_param_freectx;
22 static OSSL_OP_serializer_serialize_data_fn ec_param_der_data;
23 static OSSL_OP_serializer_serialize_object_fn ec_param_der;
24 static OSSL_OP_serializer_serialize_data_fn ec_param_pem_data;
25 static OSSL_OP_serializer_serialize_object_fn ec_param_pem;
26
27 static OSSL_OP_serializer_serialize_data_fn ec_param_print_data;
28 static OSSL_OP_serializer_serialize_object_fn ec_param_print;
29
30
31 /* There is no specific implementation context, so use the provider context */
32 static void *ec_param_newctx(void *provctx)
33 {
34     return provctx;
35 }
36
37 static void ec_param_freectx(void *vctx)
38 {
39 }
40
41 /* Public key : DER */
42 static int ec_param_der_data(void *vctx, const OSSL_PARAM params[], BIO *out,
43                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
44 {
45     OSSL_OP_keymgmt_new_fn *ec_new;
46     OSSL_OP_keymgmt_free_fn *ec_free;
47     OSSL_OP_keymgmt_import_fn *ec_import;
48     int ok = 0;
49
50     ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
51
52     if (ec_import != NULL) {
53         EC_KEY *eckey;
54
55         /* vctx == provctx */
56         if ((eckey = ec_new(vctx)) != NULL
57             && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
58             && ec_param_der(vctx, eckey, out, cb, cbarg))
59             ok = 1;
60         ec_free(eckey);
61     }
62     return ok;
63 }
64
65 static int ec_param_der(void *vctx, void *eckey, BIO *out,
66                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
67 {
68     return i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey));
69 }
70
71 /* Public key : PEM */
72 static int ec_param_pem_data(void *vctx, const OSSL_PARAM params[], BIO *out,
73                               OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
74 {
75     OSSL_OP_keymgmt_new_fn *ec_new;
76     OSSL_OP_keymgmt_free_fn *ec_free;
77     OSSL_OP_keymgmt_import_fn *ec_import;
78     int ok = 0;
79
80     ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
81
82     if (ec_import != NULL) {
83         EC_KEY *eckey;
84
85         /* vctx == provctx */
86         if ((eckey = ec_new(vctx)) != NULL
87             && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
88             && ec_param_pem(vctx, eckey, out, cb, cbarg))
89             ok = 1;
90         ec_free(eckey);
91     }
92     return ok;
93 }
94
95 static int ec_param_pem(void *vctx, void *eckey, BIO *out,
96                          OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
97 {
98     return PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey));
99 }
100
101 static int ec_param_print_data(void *vctx, const OSSL_PARAM params[], BIO *out,
102                                 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
103 {
104     OSSL_OP_keymgmt_new_fn *ec_new;
105     OSSL_OP_keymgmt_free_fn *ec_free;
106     OSSL_OP_keymgmt_import_fn *ec_import;
107     int ok = 0;
108
109     ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
110
111     if (ec_import != NULL) {
112         EC_KEY *eckey;
113
114         /* vctx == provctx */
115         if ((eckey = ec_new(vctx)) != NULL
116             && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
117             && ec_param_print(vctx, eckey, out, cb, cbarg))
118             ok = 1;
119         ec_free(eckey);
120     }
121     return ok;
122 }
123
124 static int ec_param_print(void *vctx, void *eckey, BIO *out,
125                            OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
126 {
127     return ossl_prov_print_eckey(out, eckey, ec_print_params);
128 }
129
130 const OSSL_DISPATCH ec_param_der_serializer_functions[] = {
131     { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
132     { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
133     { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_der_data },
134     { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_der },
135     { 0, NULL }
136 };
137
138 const OSSL_DISPATCH ec_param_pem_serializer_functions[] = {
139     { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
140     { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
141     { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_pem_data },
142     { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_pem },
143     { 0, NULL }
144 };
145
146 const OSSL_DISPATCH ec_param_text_serializer_functions[] = {
147     { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx },
148     { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx },
149     { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_print },
150     { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA,
151       (void (*)(void))ec_param_print_data },
152     { 0, NULL }
153 };