]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/implementations/encode_decode/encoder_dh_priv.c
Fix up issue on AIX caused by broken compiler handling of macro expansion
[thirdparty/openssl.git] / providers / implementations / encode_decode / encoder_dh_priv.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 /*
11 * DH low level APIs are deprecated for public use, but still ok for
12 * internal use.
13 */
14 #include "internal/deprecated.h"
15
16 #include <openssl/core_dispatch.h>
17 #include <openssl/core_names.h>
18 #include <openssl/err.h>
19 #include <openssl/pem.h>
20 #include <openssl/dh.h>
21 #include <openssl/types.h>
22 #include <openssl/params.h>
23 #include "prov/bio.h"
24 #include "prov/implementations.h"
25 #include "prov/provider_ctx.h"
26 #include "encoder_local.h"
27
28 #define DH_SELECT_PRIVATE_IMPORTABLE \
29 (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
30
31 static OSSL_FUNC_encoder_newctx_fn dh_priv_newctx;
32 static OSSL_FUNC_encoder_freectx_fn dh_priv_freectx;
33 static OSSL_FUNC_encoder_set_ctx_params_fn dh_priv_set_ctx_params;
34 static OSSL_FUNC_encoder_settable_ctx_params_fn dh_priv_settable_ctx_params;
35 static OSSL_FUNC_encoder_encode_data_fn dh_priv_der_data;
36 static OSSL_FUNC_encoder_encode_object_fn dh_priv_der;
37 static OSSL_FUNC_encoder_encode_data_fn dh_pem_priv_data;
38 static OSSL_FUNC_encoder_encode_object_fn dh_pem_priv;
39
40 static OSSL_FUNC_encoder_newctx_fn dh_print_newctx;
41 static OSSL_FUNC_encoder_freectx_fn dh_print_freectx;
42 static OSSL_FUNC_encoder_encode_data_fn dh_priv_print_data;
43 static OSSL_FUNC_encoder_encode_object_fn dh_priv_print;
44
45 /*
46 * Context used for private key encoding.
47 */
48 struct dh_priv_ctx_st {
49 void *provctx;
50
51 struct pkcs8_encrypt_ctx_st sc;
52 };
53
54 /* Private key : context */
55 static void *dh_priv_newctx(void *provctx)
56 {
57 struct dh_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
58
59 if (ctx != NULL) {
60 ctx->provctx = provctx;
61
62 /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
63 ctx->sc.pbe_nid = -1;
64 }
65 return ctx;
66 }
67
68 static void dh_priv_freectx(void *vctx)
69 {
70 struct dh_priv_ctx_st *ctx = vctx;
71
72 EVP_CIPHER_free(ctx->sc.cipher);
73 OPENSSL_free(ctx->sc.cipher_pass);
74 OPENSSL_free(ctx);
75 }
76
77 static const OSSL_PARAM *dh_priv_settable_ctx_params(ossl_unused void *provctx)
78 {
79 static const OSSL_PARAM settables[] = {
80 OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
81 OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
82 OSSL_PARAM_END,
83 };
84
85 return settables;
86 }
87
88 static int dh_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
89 {
90 struct dh_priv_ctx_st *ctx = vctx;
91 const OSSL_PARAM *p;
92
93 if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
94 != NULL) {
95 const OSSL_PARAM *propsp =
96 OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
97 const char *props = NULL;
98
99 if (p->data_type != OSSL_PARAM_UTF8_STRING)
100 return 0;
101 if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
102 return 0;
103 props = (propsp != NULL ? propsp->data : NULL);
104
105 EVP_CIPHER_free(ctx->sc.cipher);
106 ctx->sc.cipher_intent = p->data != NULL;
107 if (p->data != NULL
108 && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
109 == NULL))
110 return 0;
111 }
112 if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
113 != NULL) {
114 OPENSSL_free(ctx->sc.cipher_pass);
115 ctx->sc.cipher_pass = NULL;
116 if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
117 &ctx->sc.cipher_pass_length))
118 return 0;
119 }
120 return 1;
121 }
122
123 /* Private key : DER */
124 static int dh_priv_der_data(void *vctx, const OSSL_PARAM params[],
125 OSSL_CORE_BIO *out,
126 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
127 {
128 struct dh_priv_ctx_st *ctx = vctx;
129 OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
130 OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
131 OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
132 int ok = 0;
133
134 if (dh_import != NULL) {
135 DH *dh;
136
137 if ((dh = dh_new(ctx->provctx)) != NULL
138 && dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
139 && dh_priv_der(ctx, dh, out, cb, cbarg))
140 ok = 1;
141 dh_free(dh);
142 }
143 return ok;
144 }
145
146 static int dh_priv_der(void *vctx, void *dh, OSSL_CORE_BIO *cout,
147 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
148 {
149 struct dh_priv_ctx_st *ctx = vctx;
150 int ret;
151 BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
152
153 if (out == NULL)
154 return 0;
155
156 ctx->sc.cb = cb;
157 ctx->sc.cbarg = cbarg;
158
159 ret = ossl_prov_write_priv_der_from_obj(out, dh,
160 ossl_prov_dh_type_to_evp(dh),
161 ossl_prov_prepare_dh_params,
162 ossl_prov_dh_priv_to_der,
163 &ctx->sc);
164 BIO_free(out);
165
166 return ret;
167 }
168
169 /* Private key : PEM */
170 static int dh_pem_priv_data(void *vctx, const OSSL_PARAM params[],
171 OSSL_CORE_BIO *out,
172 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
173 {
174 struct dh_priv_ctx_st *ctx = vctx;
175 OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
176 OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
177 OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
178 int ok = 0;
179
180 if (dh_import != NULL) {
181 DH *dh;
182
183 if ((dh = dh_new(ctx->provctx)) != NULL
184 && dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
185 && dh_pem_priv(ctx->provctx, dh, out, cb, cbarg))
186 ok = 1;
187 dh_free(dh);
188 }
189 return ok;
190 }
191
192 static int dh_pem_priv(void *vctx, void *dh, OSSL_CORE_BIO *cout,
193 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
194 {
195 struct dh_priv_ctx_st *ctx = vctx;
196 int ret;
197 BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
198
199 if (out == NULL)
200 return 0;
201
202 ctx->sc.cb = cb;
203 ctx->sc.cbarg = cbarg;
204
205 ret = ossl_prov_write_priv_pem_from_obj(out, dh,
206 ossl_prov_dh_type_to_evp(dh),
207 ossl_prov_prepare_dh_params,
208 ossl_prov_dh_priv_to_der,
209 &ctx->sc);
210 BIO_free(out);
211
212 return ret;
213 }
214
215 /*
216 * There's no specific print context, so we use the provider context
217 */
218 static void *dh_print_newctx(void *provctx)
219 {
220 return provctx;
221 }
222
223 static void dh_print_freectx(void *ctx)
224 {
225 }
226
227 static int dh_priv_print_data(void *vctx, const OSSL_PARAM params[],
228 OSSL_CORE_BIO *out,
229 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
230 {
231 struct dh_priv_ctx_st *ctx = vctx;
232 OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
233 OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
234 OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
235 int ok = 0;
236
237 if (dh_import != NULL) {
238 DH *dh;
239
240 if ((dh = dh_new(ctx->provctx)) != NULL
241 && dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
242 && dh_priv_print(ctx, dh, out, cb, cbarg))
243 ok = 1;
244 dh_free(dh);
245 }
246 return ok;
247 }
248
249 static int dh_priv_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
250 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
251 {
252 BIO *out = bio_new_from_core_bio(ctx, cout);
253 int ret;
254
255 if (out == NULL)
256 return 0;
257
258 ret = ossl_prov_print_dh(out, dh, dh_print_priv);
259 BIO_free(out);
260
261 return ret;
262 }
263
264 const OSSL_DISPATCH dh_priv_der_encoder_functions[] = {
265 { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_priv_newctx },
266 { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_priv_freectx },
267 { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
268 (void (*)(void))dh_priv_set_ctx_params },
269 { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
270 (void (*)(void))dh_priv_settable_ctx_params },
271 { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_priv_der_data },
272 { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_priv_der },
273 { 0, NULL }
274 };
275
276 const OSSL_DISPATCH dh_priv_pem_encoder_functions[] = {
277 { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_priv_newctx },
278 { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_priv_freectx },
279 { OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
280 (void (*)(void))dh_priv_set_ctx_params },
281 { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
282 (void (*)(void))dh_priv_settable_ctx_params },
283 { OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pem_priv_data },
284 { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pem_priv },
285 { 0, NULL }
286 };
287
288 const OSSL_DISPATCH dh_priv_text_encoder_functions[] = {
289 { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_print_newctx },
290 { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_print_freectx },
291 { OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_priv_print },
292 { OSSL_FUNC_ENCODER_ENCODE_DATA,
293 (void (*)(void))dh_priv_print_data },
294 { 0, NULL }
295 };