summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/gost/gostr341001_ameth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/gost/gostr341001_ameth.c')
-rw-r--r--src/lib/libcrypto/gost/gostr341001_ameth.c737
1 files changed, 0 insertions, 737 deletions
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c
deleted file mode 100644
index 3153d2f2eb..0000000000
--- a/src/lib/libcrypto/gost/gostr341001_ameth.c
+++ /dev/null
@@ -1,737 +0,0 @@
1/* $OpenBSD: gostr341001_ameth.c,v 1.9 2015/02/14 06:40:04 jsing Exp $ */
2/*
3 * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
4 * Copyright (c) 2005-2006 Cryptocom LTD
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this
19 * software must display the following acknowledgment:
20 * "This product includes software developed by the OpenSSL Project
21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22 *
23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24 * endorse or promote products derived from this software without
25 * prior written permission. For written permission, please contact
26 * openssl-core@openssl.org.
27 *
28 * 5. Products derived from this software may not be called "OpenSSL"
29 * nor may "OpenSSL" appear in their names without prior written
30 * permission of the OpenSSL Project.
31 *
32 * 6. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by the OpenSSL Project
35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48 * OF THE POSSIBILITY OF SUCH DAMAGE.
49 * ====================================================================
50 */
51
52#include <string.h>
53
54#include <openssl/opensslconf.h>
55
56#ifndef OPENSSL_NO_GOST
57#include <openssl/bn.h>
58#include <openssl/evp.h>
59#include <openssl/ec.h>
60#include <openssl/err.h>
61#include <openssl/x509.h>
62#include <openssl/gost.h>
63
64#ifndef OPENSSL_NO_CMS
65#include <openssl/cms.h>
66#endif
67
68#include "asn1_locl.h"
69#include "gost_locl.h"
70#include "gost_asn1.h"
71
72static void
73pkey_free_gost01(EVP_PKEY *key)
74{
75 GOST_KEY_free(key->pkey.gost);
76}
77
78/*
79 * Parses GOST algorithm parameters from X509_ALGOR and
80 * modifies pkey setting NID and parameters
81 */
82static int
83decode_gost01_algor_params(EVP_PKEY *pkey, const unsigned char **p, int len)
84{
85 int param_nid = NID_undef, digest_nid = NID_undef;
86 GOST_KEY_PARAMS *gkp = NULL;
87 EC_GROUP *group;
88 GOST_KEY *ec;
89
90 gkp = d2i_GOST_KEY_PARAMS(NULL, p, len);
91 if (gkp == NULL) {
92 GOSTerr(GOST_F_DECODE_GOST01_ALGOR_PARAMS,
93 GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
94 return 0;
95 }
96 param_nid = OBJ_obj2nid(gkp->key_params);
97 digest_nid = OBJ_obj2nid(gkp->hash_params);
98 GOST_KEY_PARAMS_free(gkp);
99
100 ec = pkey->pkey.gost;
101 if (ec == NULL) {
102 ec = GOST_KEY_new();
103 if (ec == NULL)
104 return 0;
105 if (EVP_PKEY_assign_GOST(pkey, ec) == 0)
106 return 0;
107 }
108
109 group = EC_GROUP_new_by_curve_name(param_nid);
110 if (group == NULL)
111 return 0;
112 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
113 if (GOST_KEY_set_group(ec, group) == 0) {
114 EC_GROUP_free(group);
115 return 0;
116 }
117 EC_GROUP_free(group);
118 if (GOST_KEY_set_digest(ec, digest_nid) == 0)
119 return 0;
120 return 1;
121}
122
123static ASN1_STRING *
124encode_gost01_algor_params(const EVP_PKEY *key)
125{
126 ASN1_STRING *params = ASN1_STRING_new();
127 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
128 int pkey_param_nid = NID_undef;
129
130 if (params == NULL || gkp == NULL) {
131 GOSTerr(GOST_F_ENCODE_GOST01_ALGOR_PARAMS,
132 ERR_R_MALLOC_FAILURE);
133 ASN1_STRING_free(params);
134 params = NULL;
135 goto err;
136 }
137
138 pkey_param_nid =
139 EC_GROUP_get_curve_name(GOST_KEY_get0_group(key->pkey.gost));
140 gkp->key_params = OBJ_nid2obj(pkey_param_nid);
141 gkp->hash_params = OBJ_nid2obj(GOST_KEY_get_digest(key->pkey.gost));
142 /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */
143 params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
144 if (params->length <= 0) {
145 GOSTerr(GOST_F_ENCODE_GOST01_ALGOR_PARAMS,
146 ERR_R_MALLOC_FAILURE);
147 ASN1_STRING_free(params);
148 params = NULL;
149 goto err;
150 }
151 params->type = V_ASN1_SEQUENCE;
152err:
153 GOST_KEY_PARAMS_free(gkp);
154 return params;
155}
156
157static int
158pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
159{
160 const GOST_KEY *ea = a->pkey.gost;
161 const GOST_KEY *eb = b->pkey.gost;
162 const EC_POINT *ka, *kb;
163 int ret = 0;
164
165 if (ea == NULL || eb == NULL)
166 return 0;
167 ka = GOST_KEY_get0_public_key(ea);
168 kb = GOST_KEY_get0_public_key(eb);
169 if (ka == NULL || kb == NULL)
170 return 0;
171 ret = (0 == EC_POINT_cmp(GOST_KEY_get0_group(ea), ka, kb, NULL));
172 return ret;
173}
174
175static int
176pkey_size_gost01(const EVP_PKEY *pk)
177{
178 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512)
179 return 128;
180 return 64;
181}
182
183static int
184pkey_bits_gost01(const EVP_PKEY *pk)
185{
186 if (GOST_KEY_get_digest(pk->pkey.gost) == NID_id_tc26_gost3411_2012_512)
187 return 512;
188 return 256;
189}
190
191static int
192pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
193{
194 X509_ALGOR *palg = NULL;
195 const unsigned char *pubkey_buf = NULL;
196 const unsigned char *p;
197 ASN1_OBJECT *palgobj = NULL;
198 int pub_len;
199 BIGNUM *X, *Y;
200 ASN1_OCTET_STRING *octet = NULL;
201 int len;
202 int ret;
203 int ptype = V_ASN1_UNDEF;
204 ASN1_STRING *pval = NULL;
205
206 if (X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)
207 == 0)
208 return 0;
209 (void)EVP_PKEY_assign_GOST(pk, NULL);
210 X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg);
211 if (ptype != V_ASN1_SEQUENCE) {
212 GOSTerr(GOST_F_PUB_DECODE_GOST01,
213 GOST_R_BAD_KEY_PARAMETERS_FORMAT);
214 return 0;
215 }
216 p = pval->data;
217 if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
218 return 0;
219
220 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
221 if (octet == NULL) {
222 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
223 return 0;
224 }
225 len = octet->length / 2;
226
227 X = GOST_le2bn(octet->data, len, NULL);
228 Y = GOST_le2bn(octet->data + len, len, NULL);
229
230 ASN1_OCTET_STRING_free(octet);
231
232 ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y);
233 if (ret == 0)
234 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
235
236 BN_free(X);
237 BN_free(Y);
238
239 return ret;
240}
241
242static int
243pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
244{
245 ASN1_OBJECT *algobj = NULL;
246 ASN1_OCTET_STRING *octet = NULL;
247 ASN1_STRING *params = NULL;
248 void *pval = NULL;
249 unsigned char *buf = NULL, *sptr;
250 int key_size, ret = 0;
251 const EC_POINT *pub_key;
252 BIGNUM *X = NULL, *Y = NULL;
253 const GOST_KEY *ec = pk->pkey.gost;
254 int ptype = V_ASN1_UNDEF;
255
256 algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec)));
257 if (pk->save_parameters) {
258 params = encode_gost01_algor_params(pk);
259 if (params == NULL)
260 return 0;
261 pval = params;
262 ptype = V_ASN1_SEQUENCE;
263 }
264
265 key_size = GOST_KEY_get_size(ec);
266
267 pub_key = GOST_KEY_get0_public_key(ec);
268 if (pub_key == NULL) {
269 GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED);
270 goto err;
271 }
272
273 octet = ASN1_OCTET_STRING_new();
274 if (octet == NULL) {
275 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
276 goto err;
277 }
278
279 ret = ASN1_STRING_set(octet, NULL, 2 * key_size);
280 if (ret == 0) {
281 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR);
282 goto err;
283 }
284
285 sptr = ASN1_STRING_data(octet);
286
287 X = BN_new();
288 Y = BN_new();
289 if (X == NULL || Y == NULL) {
290 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE);
291 goto err;
292 }
293
294 if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec),
295 pub_key, X, Y, NULL) == 0) {
296 GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB);
297 goto err;
298 }
299
300 GOST_bn2le(X, sptr, key_size);
301 GOST_bn2le(Y, sptr + key_size, key_size);
302
303 BN_free(Y);
304 BN_free(X);
305
306 ret = i2d_ASN1_OCTET_STRING(octet, &buf);
307 ASN1_BIT_STRING_free(octet);
308 if (ret < 0)
309 return 0;
310
311 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
312
313err:
314 BN_free(Y);
315 BN_free(X);
316 ASN1_BIT_STRING_free(octet);
317 ASN1_STRING_free(params);
318 return 0;
319}
320
321static int
322param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
323{
324 int param_nid =
325 EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost));
326
327 if (BIO_indent(out, indent, 128) == 0)
328 return 0;
329 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
330 if (BIO_indent(out, indent, 128) == 0)
331 return 0;
332 BIO_printf(out, "Digest Algorithm: %s\n",
333 OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost)));
334 return 1;
335}
336
337static int
338pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
339{
340 BN_CTX *ctx = BN_CTX_new();
341 BIGNUM *X, *Y;
342 const EC_POINT *pubkey;
343 const EC_GROUP *group;
344
345 if (ctx == NULL) {
346 GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE);
347 return 0;
348 }
349 BN_CTX_start(ctx);
350 if ((X = BN_CTX_get(ctx)) == NULL)
351 goto err;
352 if ((Y = BN_CTX_get(ctx)) == NULL)
353 goto err;
354 pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost);
355 group = GOST_KEY_get0_group(pkey->pkey.gost);
356 if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y,
357 ctx) == 0) {
358 GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB);
359 goto err;
360 }
361 if (BIO_indent(out, indent, 128) == 0)
362 goto err;
363 BIO_printf(out, "Public key:\n");
364 if (BIO_indent(out, indent + 3, 128) == 0)
365 goto err;
366 BIO_printf(out, "X:");
367 BN_print(out, X);
368 BIO_printf(out, "\n");
369 BIO_indent(out, indent + 3, 128);
370 BIO_printf(out, "Y:");
371 BN_print(out, Y);
372 BIO_printf(out, "\n");
373
374 BN_CTX_end(ctx);
375 BN_CTX_free(ctx);
376
377 return param_print_gost01(out, pkey, indent, pctx);
378
379err:
380 BN_CTX_end(ctx);
381 BN_CTX_free(ctx);
382 return 0;
383}
384
385static int
386priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx)
387{
388 const BIGNUM *key;
389
390 if (BIO_indent(out, indent, 128) == 0)
391 return 0;
392 BIO_printf(out, "Private key: ");
393 key = GOST_KEY_get0_private_key(pkey->pkey.gost);
394 if (key == NULL)
395 BIO_printf(out, "<undefined)");
396 else
397 BN_print(out, key);
398 BIO_printf(out, "\n");
399
400 return pub_print_gost01(out, pkey, indent, pctx);
401}
402
403static int
404priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
405{
406 const unsigned char *pkey_buf = NULL, *p = NULL;
407 int priv_len = 0;
408 BIGNUM *pk_num = NULL;
409 int ret = 0;
410 X509_ALGOR *palg = NULL;
411 ASN1_OBJECT *palg_obj = NULL;
412 ASN1_INTEGER *priv_key = NULL;
413 GOST_KEY *ec;
414 int ptype = V_ASN1_UNDEF;
415 ASN1_STRING *pval = NULL;
416
417 if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0)
418 return 0;
419 (void)EVP_PKEY_assign_GOST(pk, NULL);
420 X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg);
421 if (ptype != V_ASN1_SEQUENCE) {
422 GOSTerr(GOST_F_PUB_DECODE_GOST01,
423 GOST_R_BAD_KEY_PARAMETERS_FORMAT);
424 return 0;
425 }
426 p = pval->data;
427 if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
428 return 0;
429 p = pkey_buf;
430 if (V_ASN1_OCTET_STRING == *p) {
431 /* New format - Little endian octet string */
432 unsigned char rev_buf[32];
433 int i;
434 ASN1_OCTET_STRING *s =
435 d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
436
437 if (s == NULL || s->length != 32) {
438 GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR);
439 ASN1_STRING_free(s);
440 return 0;
441 }
442 for (i = 0; i < 32; i++) {
443 rev_buf[31 - i] = s->data[i];
444 }
445 ASN1_STRING_free(s);
446 pk_num = BN_bin2bn(rev_buf, 32, NULL);
447 } else {
448 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
449 if (priv_key == NULL)
450 return 0;
451 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
452 ASN1_INTEGER_free(priv_key);
453 if (ret == 0) {
454 GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR);
455 return 0;
456 }
457 }
458
459 ec = pk->pkey.gost;
460 if (ec == NULL) {
461 ec = GOST_KEY_new();
462 if (ec == NULL) {
463 BN_free(pk_num);
464 return 0;
465 }
466 if (EVP_PKEY_assign_GOST(pk, ec) == 0) {
467 BN_free(pk_num);
468 GOST_KEY_free(ec);
469 return 0;
470 }
471 }
472 if (GOST_KEY_set_private_key(ec, pk_num) == 0) {
473 BN_free(pk_num);
474 return 0;
475 }
476 ret = 0;
477 if (EVP_PKEY_missing_parameters(pk) == 0)
478 ret = gost2001_compute_public(ec) != 0;
479 BN_free(pk_num);
480
481 return ret;
482}
483
484static int
485priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
486{
487 ASN1_OBJECT *algobj =
488 OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost)));
489 ASN1_STRING *params = encode_gost01_algor_params(pk);
490 unsigned char *priv_buf = NULL;
491 int priv_len;
492 ASN1_INTEGER *asn1key = NULL;
493
494 if (params == NULL)
495 return 0;
496
497 asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost),
498 NULL);
499 if (asn1key == NULL) {
500 ASN1_STRING_free(params);
501 return 0;
502 }
503 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf);
504 ASN1_INTEGER_free(asn1key);
505 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf,
506 priv_len);
507}
508
509static int
510param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder)
511{
512 ASN1_STRING *params = encode_gost01_algor_params(pkey);
513 int len;
514
515 if (params == NULL)
516 return 0;
517 len = params->length;
518 if (pder != NULL)
519 memcpy(*pder, params->data, params->length);
520 ASN1_STRING_free(params);
521 return len;
522}
523
524static int
525param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
526{
527 ASN1_OBJECT *obj = NULL;
528 int nid;
529 GOST_KEY *ec;
530 EC_GROUP *group;
531 int ret;
532
533 /* New format */
534 if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder)
535 return decode_gost01_algor_params(pkey, pder, derlen);
536
537 /* Compatibility */
538 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
539 GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
540 return 0;
541 }
542 nid = OBJ_obj2nid(obj);
543 ASN1_OBJECT_free(obj);
544
545 ec = GOST_KEY_new();
546 if (ec == NULL) {
547 GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
548 return 0;
549 }
550 group = EC_GROUP_new_by_curve_name(nid);
551 if (group == NULL) {
552 GOSTerr(GOST_F_PARAM_DECODE_GOST01,
553 EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
554 GOST_KEY_free(ec);
555 return 0;
556 }
557
558 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
559 if (GOST_KEY_set_group(ec, group) == 0) {
560 GOSTerr(GOST_F_PARAM_DECODE_GOST01, ERR_R_EC_LIB);
561 EC_GROUP_free(group);
562 GOST_KEY_free(ec);
563 return 0;
564 }
565 EC_GROUP_free(group);
566 if (GOST_KEY_set_digest(ec,
567 NID_id_GostR3411_94_CryptoProParamSet) == 0) {
568 GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE);
569 GOST_KEY_free(ec);
570 return 0;
571 }
572 ret = EVP_PKEY_assign_GOST(pkey, ec);
573 if (ret == 0)
574 GOST_KEY_free(ec);
575 return ret;
576}
577
578static int
579param_missing_gost01(const EVP_PKEY *pk)
580{
581 const GOST_KEY *ec = pk->pkey.gost;
582
583 if (ec == NULL)
584 return 1;
585 if (GOST_KEY_get0_group(ec) == NULL)
586 return 1;
587 if (GOST_KEY_get_digest(ec) == NID_undef)
588 return 1;
589 return 0;
590}
591
592static int
593param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
594{
595 GOST_KEY *eto = to->pkey.gost;
596 const GOST_KEY *efrom = from->pkey.gost;
597 int ret = 1;
598
599 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
600 GOSTerr(GOST_F_PARAM_COPY_GOST01,
601 GOST_R_INCOMPATIBLE_ALGORITHMS);
602 return 0;
603 }
604 if (efrom == NULL) {
605 GOSTerr(GOST_F_PARAM_COPY_GOST01,
606 GOST_R_KEY_PARAMETERS_MISSING);
607 return 0;
608 }
609 if (eto == NULL) {
610 eto = GOST_KEY_new();
611 if (eto == NULL) {
612 GOSTerr(GOST_F_PARAM_COPY_GOST01,
613 ERR_R_MALLOC_FAILURE);
614 return 0;
615 }
616 if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) {
617 GOST_KEY_free(eto);
618 return 0;
619 }
620 }
621 GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom));
622 GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom));
623 if (GOST_KEY_get0_private_key(eto) != NULL)
624 ret = gost2001_compute_public(eto);
625
626 return ret;
627}
628
629static int
630param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
631{
632 if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) !=
633 EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost)))
634 return 0;
635
636 if (GOST_KEY_get_digest(a->pkey.gost) !=
637 GOST_KEY_get_digest(b->pkey.gost))
638 return 0;
639
640 return 1;
641}
642
643static int
644pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2)
645{
646 X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL;
647 int digest = GOST_KEY_get_digest(pkey->pkey.gost);
648
649 switch (op) {
650 case ASN1_PKEY_CTRL_PKCS7_SIGN:
651 if (arg1 == 0)
652 PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
653 break;
654
655 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
656 if (arg1 == 0)
657 PKCS7_RECIP_INFO_get0_alg(arg2, &alg3);
658 break;
659#ifndef OPENSSL_NO_CMS
660 case ASN1_PKEY_CTRL_CMS_SIGN:
661 if (arg1 == 0)
662 CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
663 break;
664
665 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
666 if (arg1 == 0)
667 CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg3);
668 break;
669#endif
670 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
671 *(int *)arg2 = GostR3410_get_md_digest(digest);
672 return 2;
673
674 default:
675 return -2;
676 }
677
678 if (alg1)
679 X509_ALGOR_set0(alg1, OBJ_nid2obj(GostR3410_get_md_digest(digest)), V_ASN1_NULL, 0);
680 if (alg2)
681 X509_ALGOR_set0(alg2, OBJ_nid2obj(GostR3410_get_pk_digest(digest)), V_ASN1_NULL, 0);
682 if (alg3) {
683 ASN1_STRING *params = encode_gost01_algor_params(pkey);
684 if (params == NULL) {
685 return -1;
686 }
687 X509_ALGOR_set0(alg3,
688 OBJ_nid2obj(GostR3410_get_pk_digest(digest)),
689 V_ASN1_SEQUENCE, params);
690 }
691
692 return 1;
693}
694
695const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[] = {
696 {
697 .pkey_id = EVP_PKEY_GOSTR01,
698 .pkey_base_id = EVP_PKEY_GOSTR01,
699 .pkey_flags = ASN1_PKEY_SIGPARAM_NULL,
700
701 .pem_str = "GOST2001",
702 .info = "GOST R 34.10-2001",
703
704 .pkey_free = pkey_free_gost01,
705 .pkey_ctrl = pkey_ctrl_gost01,
706
707 .priv_decode = priv_decode_gost01,
708 .priv_encode = priv_encode_gost01,
709 .priv_print = priv_print_gost01,
710
711 .param_decode = param_decode_gost01,
712 .param_encode = param_encode_gost01,
713 .param_missing = param_missing_gost01,
714 .param_copy = param_copy_gost01,
715 .param_cmp = param_cmp_gost01,
716 .param_print = param_print_gost01,
717
718 .pub_decode = pub_decode_gost01,
719 .pub_encode = pub_encode_gost01,
720 .pub_cmp = pub_cmp_gost01,
721 .pub_print = pub_print_gost01,
722 .pkey_size = pkey_size_gost01,
723 .pkey_bits = pkey_bits_gost01,
724 },
725 {
726 .pkey_id = EVP_PKEY_GOSTR12_256,
727 .pkey_base_id = EVP_PKEY_GOSTR01,
728 .pkey_flags = ASN1_PKEY_ALIAS
729 },
730 {
731 .pkey_id = EVP_PKEY_GOSTR12_512,
732 .pkey_base_id = EVP_PKEY_GOSTR01,
733 .pkey_flags = ASN1_PKEY_ALIAS
734 },
735};
736
737#endif