GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/gost/gostr341001_ameth.c Lines: 0 363 0.0 %
Date: 2016-12-06 Branches: 0 160 0.0 %

Line Branch Exec Source
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
72
static void
73
pkey_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
 */
82
static int
83
decode_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
123
static ASN1_STRING *
124
encode_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;
152
err:
153
	GOST_KEY_PARAMS_free(gkp);
154
	return params;
155
}
156
157
static int
158
pub_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
175
static int
176
pkey_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
183
static int
184
pkey_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
191
static int
192
pub_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
242
static int
243
pub_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
313
err:
314
	BN_free(Y);
315
	BN_free(X);
316
	ASN1_BIT_STRING_free(octet);
317
	ASN1_STRING_free(params);
318
	return 0;
319
}
320
321
static int
322
param_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
337
static int
338
pub_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
379
err:
380
	BN_CTX_end(ctx);
381
	BN_CTX_free(ctx);
382
	return 0;
383
}
384
385
static int
386
priv_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
403
static int
404
priv_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
484
static int
485
priv_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
509
static int
510
param_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
524
static int
525
param_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
578
static int
579
param_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
592
static int
593
param_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
629
static int
630
param_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
643
static int
644
pkey_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
695
const 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