Deleted Added
full compact
gost_ameth.c (267258) gost_ameth.c (280304)
1/**********************************************************************
2 * gost_ameth.c *
3 * Copyright (c) 2005-2006 Cryptocom LTD *
4 * This file is distributed under the same license as OpenSSL *
5 * *
6 * Implementation of RFC 4490/4491 ASN1 method *
7 * for OpenSSL *
8 * Requires OpenSSL 0.9.9 for compilation *
9 **********************************************************************/
10#include <string.h>
11#include <openssl/crypto.h>
12#include <openssl/err.h>
13#include <openssl/engine.h>
14#include <openssl/evp.h>
15#include <openssl/asn1.h>
16#ifndef OPENSSL_NO_CMS
1/**********************************************************************
2 * gost_ameth.c *
3 * Copyright (c) 2005-2006 Cryptocom LTD *
4 * This file is distributed under the same license as OpenSSL *
5 * *
6 * Implementation of RFC 4490/4491 ASN1 method *
7 * for OpenSSL *
8 * Requires OpenSSL 0.9.9 for compilation *
9 **********************************************************************/
10#include <string.h>
11#include <openssl/crypto.h>
12#include <openssl/err.h>
13#include <openssl/engine.h>
14#include <openssl/evp.h>
15#include <openssl/asn1.h>
16#ifndef OPENSSL_NO_CMS
17#include
17# include <openssl/cms.h>
18#endif
19#include "gost_params.h"
20#include "gost_lcl.h"
21#include "e_gost_err.h"
22
18#endif
19#include "gost_params.h"
20#include "gost_lcl.h"
21#include "e_gost_err.h"
22
23int gost94_nid_by_params(DSA *p)
24 {
25 R3410_params *gost_params;
26 BIGNUM *q=BN_new();
27 for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++)
28 {
29 BN_dec2bn(&q,gost_params->q);
30 if (!BN_cmp(q,p->q))
31 {
32 BN_free(q);
33 return gost_params->nid;
34 }
35 }
36 BN_free(q);
37 return NID_undef;
38 }
23int gost94_nid_by_params(DSA *p)
24{
25 R3410_params *gost_params;
26 BIGNUM *q = BN_new();
27 for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) {
28 BN_dec2bn(&q, gost_params->q);
29 if (!BN_cmp(q, p->q)) {
30 BN_free(q);
31 return gost_params->nid;
32 }
33 }
34 BN_free(q);
35 return NID_undef;
36}
39
37
40static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
41 {
42 ASN1_STRING *params = ASN1_STRING_new();
43 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
44 int pkey_param_nid = NID_undef;
38static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
39{
40 ASN1_STRING *params = ASN1_STRING_new();
41 GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
42 int pkey_param_nid = NID_undef;
45
43
46 if (!params || !gkp)
47 {
48 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
49 ERR_R_MALLOC_FAILURE);
50 ASN1_STRING_free(params);
51 params = NULL;
52 goto err;
53 }
54 switch (EVP_PKEY_base_id(key))
55 {
56 case NID_id_GostR3410_2001:
57 pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key)));
58 break;
59 case NID_id_GostR3410_94:
60 pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
61 if (pkey_param_nid == NID_undef)
62 {
63 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
64 GOST_R_INVALID_GOST94_PARMSET);
65 ASN1_STRING_free(params);
66 params=NULL;
67 goto err;
68 }
69 break;
70 }
71 gkp->key_params = OBJ_nid2obj(pkey_param_nid);
72 gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
73 /*gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);*/
74 params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
75 if (params->length <=0 )
76 {
77 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
78 ERR_R_MALLOC_FAILURE);
79 ASN1_STRING_free(params);
80 params = NULL;
81 goto err;
82 }
83 params ->type = V_ASN1_SEQUENCE;
84 err:
85 GOST_KEY_PARAMS_free(gkp);
86 return params;
87 }
44 if (!params || !gkp) {
45 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
46 ASN1_STRING_free(params);
47 params = NULL;
48 goto err;
49 }
50 switch (EVP_PKEY_base_id(key)) {
51 case NID_id_GostR3410_2001:
52 pkey_param_nid =
53 EC_GROUP_get_curve_name(EC_KEY_get0_group
54 (EVP_PKEY_get0((EVP_PKEY *)key)));
55 break;
56 case NID_id_GostR3410_94:
57 pkey_param_nid =
58 (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
59 if (pkey_param_nid == NID_undef) {
60 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
61 GOST_R_INVALID_GOST94_PARMSET);
62 ASN1_STRING_free(params);
63 params = NULL;
64 goto err;
65 }
66 break;
67 }
68 gkp->key_params = OBJ_nid2obj(pkey_param_nid);
69 gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet);
70 /*
71 * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid);
72 */
73 params->length = i2d_GOST_KEY_PARAMS(gkp, &params->data);
74 if (params->length <= 0) {
75 GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE);
76 ASN1_STRING_free(params);
77 params = NULL;
78 goto err;
79 }
80 params->type = V_ASN1_SEQUENCE;
81 err:
82 GOST_KEY_PARAMS_free(gkp);
83 return params;
84}
88
85
89/* Parses GOST algorithm parameters from X509_ALGOR and
90 * modifies pkey setting NID and parameters
86/*
87 * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting
88 * NID and parameters
91 */
89 */
92static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
93 {
94 ASN1_OBJECT *palg_obj =NULL;
95 int ptype = V_ASN1_UNDEF;
96 int pkey_nid = NID_undef,param_nid = NID_undef;
97 void *_pval;
98 ASN1_STRING *pval = NULL;
99 const unsigned char *p;
100 GOST_KEY_PARAMS *gkp = NULL;
90static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
91{
92 ASN1_OBJECT *palg_obj = NULL;
93 int ptype = V_ASN1_UNDEF;
94 int pkey_nid = NID_undef, param_nid = NID_undef;
95 void *_pval;
96 ASN1_STRING *pval = NULL;
97 const unsigned char *p;
98 GOST_KEY_PARAMS *gkp = NULL;
101
99
102 X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
103 pval = _pval;
104 if (ptype != V_ASN1_SEQUENCE)
105 {
106 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
107 GOST_R_BAD_KEY_PARAMETERS_FORMAT);
108 return 0;
109 }
110 p=pval->data;
111 pkey_nid = OBJ_obj2nid(palg_obj);
100 X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg);
101 pval = _pval;
102 if (ptype != V_ASN1_SEQUENCE) {
103 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
104 GOST_R_BAD_KEY_PARAMETERS_FORMAT);
105 return 0;
106 }
107 p = pval->data;
108 pkey_nid = OBJ_obj2nid(palg_obj);
112
109
113 gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length);
114 if (!gkp)
115 {
116 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
117 GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
118 return 0;
119 }
120 param_nid = OBJ_obj2nid(gkp->key_params);
121 GOST_KEY_PARAMS_free(gkp);
122 EVP_PKEY_set_type(pkey,pkey_nid);
123 switch (pkey_nid)
124 {
125 case NID_id_GostR3410_94:
126 {
127 DSA *dsa= EVP_PKEY_get0(pkey);
128 if (!dsa)
129 {
130 dsa = DSA_new();
131 if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0;
132 }
133 if (!fill_GOST94_params(dsa,param_nid)) return 0;
134 break;
135 }
136 case NID_id_GostR3410_2001:
137 {
138 EC_KEY *ec = EVP_PKEY_get0(pkey);
139 if (!ec)
140 {
141 ec = EC_KEY_new();
142 if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0;
143 }
144 if (!fill_GOST2001_params(ec,param_nid)) return 0;
145 }
146 }
110 gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length);
111 if (!gkp) {
112 GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
113 GOST_R_BAD_PKEY_PARAMETERS_FORMAT);
114 return 0;
115 }
116 param_nid = OBJ_obj2nid(gkp->key_params);
117 GOST_KEY_PARAMS_free(gkp);
118 EVP_PKEY_set_type(pkey, pkey_nid);
119 switch (pkey_nid) {
120 case NID_id_GostR3410_94:
121 {
122 DSA *dsa = EVP_PKEY_get0(pkey);
123 if (!dsa) {
124 dsa = DSA_new();
125 if (!EVP_PKEY_assign(pkey, pkey_nid, dsa))
126 return 0;
127 }
128 if (!fill_GOST94_params(dsa, param_nid))
129 return 0;
130 break;
131 }
132 case NID_id_GostR3410_2001:
133 {
134 EC_KEY *ec = EVP_PKEY_get0(pkey);
135 if (!ec) {
136 ec = EC_KEY_new();
137 if (!EVP_PKEY_assign(pkey, pkey_nid, ec))
138 return 0;
139 }
140 if (!fill_GOST2001_params(ec, param_nid))
141 return 0;
142 }
143 }
147
144
148 return 1;
149 }
145 return 1;
146}
150
147
151static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
152 {
153 switch (EVP_PKEY_base_id(pkey))
154 {
155 case NID_id_GostR3410_94:
156 {
157 DSA *dsa = EVP_PKEY_get0(pkey);
158 if (!dsa)
159 {
160 dsa = DSA_new();
161 EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
162 }
163 dsa->priv_key = BN_dup(priv);
164 if (!EVP_PKEY_missing_parameters(pkey))
165 gost94_compute_public(dsa);
166 break;
167 }
168 case NID_id_GostR3410_2001:
169 {
170 EC_KEY *ec = EVP_PKEY_get0(pkey);
171 if (!ec)
172 {
173 ec = EC_KEY_new();
174 EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
175 }
176 if (!EC_KEY_set_private_key(ec,priv)) return 0;
177 if (!EVP_PKEY_missing_parameters(pkey))
178 gost2001_compute_public(ec);
179 break;
180 }
181 }
182 return 1;
183 }
184BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey)
185 {
186 switch (EVP_PKEY_base_id(pkey))
187 {
188 case NID_id_GostR3410_94:
189 {
190 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
191 if (!dsa)
192 {
193 return NULL;
194 }
195 if (!dsa->priv_key) return NULL;
196 return dsa->priv_key;
197 break;
198 }
199 case NID_id_GostR3410_2001:
200 {
201 EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
202 const BIGNUM* priv;
203 if (!ec)
204 {
205 return NULL;
206 }
207 if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
208 return (BIGNUM *)priv;
209 break;
210 }
211 }
212 return NULL;
213 }
148static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv)
149{
150 switch (EVP_PKEY_base_id(pkey)) {
151 case NID_id_GostR3410_94:
152 {
153 DSA *dsa = EVP_PKEY_get0(pkey);
154 if (!dsa) {
155 dsa = DSA_new();
156 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa);
157 }
158 dsa->priv_key = BN_dup(priv);
159 if (!EVP_PKEY_missing_parameters(pkey))
160 gost94_compute_public(dsa);
161 break;
162 }
163 case NID_id_GostR3410_2001:
164 {
165 EC_KEY *ec = EVP_PKEY_get0(pkey);
166 if (!ec) {
167 ec = EC_KEY_new();
168 EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec);
169 }
170 if (!EC_KEY_set_private_key(ec, priv))
171 return 0;
172 if (!EVP_PKEY_missing_parameters(pkey))
173 gost2001_compute_public(ec);
174 break;
175 }
176 }
177 return 1;
178}
214
179
215static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
216 long arg1, void *arg2)
217 {
218 switch (op)
219 {
220 case ASN1_PKEY_CTRL_PKCS7_SIGN:
221 if (arg1 == 0)
222 {
223 X509_ALGOR *alg1 = NULL, *alg2 = NULL;
224 int nid = EVP_PKEY_base_id(pkey);
225 PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2,
226 NULL, &alg1, &alg2);
227 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
228 V_ASN1_NULL, 0);
229 if (nid == NID_undef)
230 {
231 return (-1);
232 }
233 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
234 }
235 return 1;
180BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey)
181{
182 switch (EVP_PKEY_base_id(pkey)) {
183 case NID_id_GostR3410_94:
184 {
185 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
186 if (!dsa) {
187 return NULL;
188 }
189 if (!dsa->priv_key)
190 return NULL;
191 return dsa->priv_key;
192 break;
193 }
194 case NID_id_GostR3410_2001:
195 {
196 EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
197 const BIGNUM *priv;
198 if (!ec) {
199 return NULL;
200 }
201 if (!(priv = EC_KEY_get0_private_key(ec)))
202 return NULL;
203 return (BIGNUM *)priv;
204 break;
205 }
206 }
207 return NULL;
208}
209
210static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
211{
212 switch (op) {
213 case ASN1_PKEY_CTRL_PKCS7_SIGN:
214 if (arg1 == 0) {
215 X509_ALGOR *alg1 = NULL, *alg2 = NULL;
216 int nid = EVP_PKEY_base_id(pkey);
217 PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2,
218 NULL, &alg1, &alg2);
219 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
220 V_ASN1_NULL, 0);
221 if (nid == NID_undef) {
222 return (-1);
223 }
224 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
225 }
226 return 1;
236#ifndef OPENSSL_NO_CMS
227#ifndef OPENSSL_NO_CMS
237 case ASN1_PKEY_CTRL_CMS_SIGN:
238 if (arg1 == 0)
239 {
240 X509_ALGOR *alg1 = NULL, *alg2 = NULL;
241 int nid = EVP_PKEY_base_id(pkey);
242 CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2,
243 NULL, NULL, &alg1, &alg2);
244 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
245 V_ASN1_NULL, 0);
246 if (nid == NID_undef)
247 {
248 return (-1);
249 }
250 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
251 }
252 return 1;
228 case ASN1_PKEY_CTRL_CMS_SIGN:
229 if (arg1 == 0) {
230 X509_ALGOR *alg1 = NULL, *alg2 = NULL;
231 int nid = EVP_PKEY_base_id(pkey);
232 CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2,
233 NULL, NULL, &alg1, &alg2);
234 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
235 V_ASN1_NULL, 0);
236 if (nid == NID_undef) {
237 return (-1);
238 }
239 X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
240 }
241 return 1;
253#endif
242#endif
254 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
255 if (arg1 == 0)
256 {
257 X509_ALGOR *alg;
258 ASN1_STRING * params = encode_gost_algor_params(pkey);
259 if (!params)
260 {
261 return -1;
262 }
263 PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg);
264 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
265 V_ASN1_SEQUENCE, params);
266 }
267 return 1;
243 case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
244 if (arg1 == 0) {
245 X509_ALGOR *alg;
246 ASN1_STRING *params = encode_gost_algor_params(pkey);
247 if (!params) {
248 return -1;
249 }
250 PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg);
251 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
252 V_ASN1_SEQUENCE, params);
253 }
254 return 1;
268#ifndef OPENSSL_NO_CMS
255#ifndef OPENSSL_NO_CMS
269 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
270 if (arg1 == 0)
271 {
272 X509_ALGOR *alg = NULL;
273 ASN1_STRING * params = encode_gost_algor_params(pkey);
274 if (!params)
275 {
276 return -1;
277 }
278 CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, NULL, &alg);
279 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type),
280 V_ASN1_SEQUENCE, params);
281 }
282 return 1;
256 case ASN1_PKEY_CTRL_CMS_ENVELOPE:
257 if (arg1 == 0) {
258 X509_ALGOR *alg = NULL;
259 ASN1_STRING *params = encode_gost_algor_params(pkey);
260 if (!params) {
261 return -1;
262 }
263 CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL,
264 NULL, &alg);
265 X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE,
266 params);
267 }
268 return 1;
283#endif
269#endif
284 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
285 *(int *)arg2 = NID_id_GostR3411_94;
286 return 2;
287 }
288
289 return -2;
290 }
291/*----------------------- free functions * ------------------------------*/
292static void pkey_free_gost94(EVP_PKEY *key)
293 {
294 if (key->pkey.dsa)
295 {
296 DSA_free(key->pkey.dsa);
297 }
298 }
270 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
271 *(int *)arg2 = NID_id_GostR3411_94;
272 return 2;
273 }
299
274
300static void pkey_free_gost01(EVP_PKEY *key)
301 {
302 if (key->pkey.ec)
303 {
304 EC_KEY_free(key->pkey.ec);
305 }
306 }
275 return -2;
276}
307
277
278/* --------------------- free functions * ------------------------------*/
279static void pkey_free_gost94(EVP_PKEY *key)
280{
281 if (key->pkey.dsa) {
282 DSA_free(key->pkey.dsa);
283 }
284}
285
286static void pkey_free_gost01(EVP_PKEY *key)
287{
288 if (key->pkey.ec) {
289 EC_KEY_free(key->pkey.ec);
290 }
291}
292
308/* ------------------ private key functions -----------------------------*/
293/* ------------------ private key functions -----------------------------*/
309static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
310 {
311 const unsigned char *pkey_buf = NULL,*p=NULL;
312 int priv_len = 0;
313 BIGNUM *pk_num=NULL;
314 int ret =0;
315 X509_ALGOR *palg =NULL;
316 ASN1_OBJECT *palg_obj = NULL;
317 ASN1_INTEGER *priv_key=NULL;
294static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
295{
296 const unsigned char *pkey_buf = NULL, *p = NULL;
297 int priv_len = 0;
298 BIGNUM *pk_num = NULL;
299 int ret = 0;
300 X509_ALGOR *palg = NULL;
301 ASN1_OBJECT *palg_obj = NULL;
302 ASN1_INTEGER *priv_key = NULL;
318
303
319 if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf))
320 return 0;
321 p = pkey_buf;
322 if (!decode_gost_algor_params(pk,palg))
323 {
324 return 0;
325 }
326 if (V_ASN1_OCTET_STRING == *p)
327 {
328 /* New format - Little endian octet string */
329 unsigned char rev_buf[32];
330 int i;
331 ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len);
332 if (!s||s->length !=32)
333 {
334 GOSTerr(GOST_F_PRIV_DECODE_GOST,
335 EVP_R_DECODE_ERROR);
336 return 0;
337 }
338 for (i=0;i<32;i++)
339 {
340 rev_buf[31-i]=s->data[i];
341 }
342 ASN1_STRING_free(s);
343 pk_num = getbnfrombuf(rev_buf,32);
344 }
345 else
346 {
347 priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
348 if (!priv_key) return 0;
349 ret= ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ;
350 ASN1_INTEGER_free(priv_key);
351 if (!ret)
352 {
353 GOSTerr(GOST_F_PRIV_DECODE_GOST,
354 EVP_R_DECODE_ERROR);
355 return 0;
356 }
357 }
304 if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf))
305 return 0;
306 p = pkey_buf;
307 if (!decode_gost_algor_params(pk, palg)) {
308 return 0;
309 }
310 if (V_ASN1_OCTET_STRING == *p) {
311 /* New format - Little endian octet string */
312 unsigned char rev_buf[32];
313 int i;
314 ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
315 if (!s || s->length != 32) {
316 GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
317 return 0;
318 }
319 for (i = 0; i < 32; i++) {
320 rev_buf[31 - i] = s->data[i];
321 }
322 ASN1_STRING_free(s);
323 pk_num = getbnfrombuf(rev_buf, 32);
324 } else {
325 priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
326 if (!priv_key)
327 return 0;
328 ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
329 ASN1_INTEGER_free(priv_key);
330 if (!ret) {
331 GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
332 return 0;
333 }
334 }
358
335
359 ret= gost_set_priv_key(pk,pk_num);
360 BN_free(pk_num);
361 return ret;
362 }
336 ret = gost_set_priv_key(pk, pk_num);
337 BN_free(pk_num);
338 return ret;
339}
363
364/* ----------------------------------------------------------------------*/
365static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
340
341/* ----------------------------------------------------------------------*/
342static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
366 {
367 ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
368 ASN1_STRING *params = encode_gost_algor_params(pk);
369 unsigned char *priv_buf = NULL;
370 int priv_len;
343{
344 ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
345 ASN1_STRING *params = encode_gost_algor_params(pk);
346 unsigned char *priv_buf = NULL;
347 int priv_len;
371
348
372 ASN1_INTEGER *asn1key=NULL;
373 if (!params)
374 {
375 return 0;
376 }
377 asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk),NULL);
378 priv_len = i2d_ASN1_INTEGER(asn1key,&priv_buf);
379 ASN1_INTEGER_free(asn1key);
380 return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
381 priv_buf,priv_len);
382 }
349 ASN1_INTEGER *asn1key = NULL;
350 if (!params) {
351 return 0;
352 }
353 asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL);
354 priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf);
355 ASN1_INTEGER_free(asn1key);
356 return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params,
357 priv_buf, priv_len);
358}
359
383/* --------- printing keys --------------------------------*/
384static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
360/* --------- printing keys --------------------------------*/
361static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent,
385 ASN1_PCTX *pctx, int type)
386 {
387 int param_nid = NID_undef;
362 ASN1_PCTX *pctx, int type)
363{
364 int param_nid = NID_undef;
388
365
389 if (type == 2)
390 {
391 BIGNUM *key;
366 if (type == 2) {
367 BIGNUM *key;
392
368
393 if (!BIO_indent(out,indent,128)) return 0;
394 BIO_printf(out,"Private key: ");
395 key = gost_get0_priv_key(pkey);
396 if (!key)
397 BIO_printf(out,"<undefined>");
398 else
399 BN_print(out,key);
400 BIO_printf(out,"\n");
401 }
402 if (type >= 1)
403 {
404 BIGNUM *pubkey;
405
406 pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
407 BIO_indent(out,indent,128);
408 BIO_printf(out,"Public key: ");
409 BN_print(out,pubkey);
410 BIO_printf(out,"\n");
411 }
369 if (!BIO_indent(out, indent, 128))
370 return 0;
371 BIO_printf(out, "Private key: ");
372 key = gost_get0_priv_key(pkey);
373 if (!key)
374 BIO_printf(out, "<undefined>");
375 else
376 BN_print(out, key);
377 BIO_printf(out, "\n");
378 }
379 if (type >= 1) {
380 BIGNUM *pubkey;
412
381
413 param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
414 BIO_indent(out,indent,128);
415 BIO_printf(out, "Parameter set: %s\n",OBJ_nid2ln(param_nid));
416 return 1;
382 pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
383 BIO_indent(out, indent, 128);
384 BIO_printf(out, "Public key: ");
385 BN_print(out, pubkey);
386 BIO_printf(out, "\n");
387 }
388
389 param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
390 BIO_indent(out, indent, 128);
391 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
392 return 1;
417}
418
419static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
393}
394
395static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
420 ASN1_PCTX *pctx)
421 {
422 return print_gost_94(out, pkey, indent, pctx,0);
423 }
396 ASN1_PCTX *pctx)
397{
398 return print_gost_94(out, pkey, indent, pctx, 0);
399}
424
425static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
400
401static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
426 ASN1_PCTX *pctx)
427 {
428 return print_gost_94(out,pkey, indent, pctx,1);
429 }
430static int priv_print_gost94(BIO *out,const EVP_PKEY *pkey, int indent,
431 ASN1_PCTX *pctx)
432 {
433 return print_gost_94(out,pkey,indent,pctx,2);
434 }
402 ASN1_PCTX *pctx)
403{
404 return print_gost_94(out, pkey, indent, pctx, 1);
405}
435
406
407static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
408 ASN1_PCTX *pctx)
409{
410 return print_gost_94(out, pkey, indent, pctx, 2);
411}
412
436static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
413static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent,
437 ASN1_PCTX *pctx, int type)
438 {
439 int param_nid = NID_undef;
440 if (type == 2)
441 {
442 BIGNUM *key;
414 ASN1_PCTX *pctx, int type)
415{
416 int param_nid = NID_undef;
417 if (type == 2) {
418 BIGNUM *key;
443
419
444 if (!BIO_indent(out,indent,128)) return 0;
445 BIO_printf(out,"Private key: ");
446 key = gost_get0_priv_key(pkey);
447 if (!key)
448 BIO_printf(out,"<undefined)");
449 else
450 BN_print(out,key);
451 BIO_printf(out,"\n");
452 }
453 if (type >= 1)
454 {
455 BN_CTX *ctx = BN_CTX_new();
456 BIGNUM *X,*Y;
457 const EC_POINT *pubkey;
458 const EC_GROUP *group;
420 if (!BIO_indent(out, indent, 128))
421 return 0;
422 BIO_printf(out, "Private key: ");
423 key = gost_get0_priv_key(pkey);
424 if (!key)
425 BIO_printf(out, "<undefined)");
426 else
427 BN_print(out, key);
428 BIO_printf(out, "\n");
429 }
430 if (type >= 1) {
431 BN_CTX *ctx = BN_CTX_new();
432 BIGNUM *X, *Y;
433 const EC_POINT *pubkey;
434 const EC_GROUP *group;
459
435
460 if (!ctx)
461 {
462 GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_MALLOC_FAILURE);
463 return 0;
464 }
465 BN_CTX_start(ctx);
466 X = BN_CTX_get(ctx);
467 Y = BN_CTX_get(ctx);
468 pubkey = EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
469 group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
470 if (!EC_POINT_get_affine_coordinates_GFp(group,pubkey,X,Y,ctx))
471 {
472 GOSTerr(GOST_F_PRINT_GOST_01,ERR_R_EC_LIB);
473 BN_CTX_free(ctx);
474 return 0;
475 }
476 if (!BIO_indent(out,indent,128)) return 0;
477 BIO_printf(out,"Public key:\n");
478 if (!BIO_indent(out,indent+3,128)) return 0;
479 BIO_printf(out,"X:");
480 BN_print(out,X);
481 BIO_printf(out,"\n");
482 BIO_indent(out,indent+3,128);
483 BIO_printf(out,"Y:");
484 BN_print(out,Y);
485 BIO_printf(out,"\n");
486 BN_CTX_end(ctx);
487 BN_CTX_free(ctx);
488 }
436 if (!ctx) {
437 GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE);
438 return 0;
439 }
440 BN_CTX_start(ctx);
441 X = BN_CTX_get(ctx);
442 Y = BN_CTX_get(ctx);
443 pubkey =
444 EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
445 group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey));
446 if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) {
447 GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB);
448 BN_CTX_free(ctx);
449 return 0;
450 }
451 if (!BIO_indent(out, indent, 128))
452 return 0;
453 BIO_printf(out, "Public key:\n");
454 if (!BIO_indent(out, indent + 3, 128))
455 return 0;
456 BIO_printf(out, "X:");
457 BN_print(out, X);
458 BIO_printf(out, "\n");
459 BIO_indent(out, indent + 3, 128);
460 BIO_printf(out, "Y:");
461 BN_print(out, Y);
462 BIO_printf(out, "\n");
463 BN_CTX_end(ctx);
464 BN_CTX_free(ctx);
465 }
489
466
490 param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
491 if (!BIO_indent(out,indent,128)) return 0;
492 BIO_printf(out,"Parameter set: %s\n",OBJ_nid2ln(param_nid));
493 return 1;
467 param_nid =
468 EC_GROUP_get_curve_name(EC_KEY_get0_group
469 (EVP_PKEY_get0((EVP_PKEY *)pkey)));
470 if (!BIO_indent(out, indent, 128))
471 return 0;
472 BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid));
473 return 1;
494}
474}
475
495static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
476static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
496 ASN1_PCTX *pctx)
497 {
498 return print_gost_01(out,pkey,indent,pctx,0);
499 }
477 ASN1_PCTX *pctx)
478{
479 return print_gost_01(out, pkey, indent, pctx, 0);
480}
481
500static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
482static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
501 ASN1_PCTX *pctx)
502 {
503 return print_gost_01(out,pkey, indent, pctx,1);
504 }
505static int priv_print_gost01(BIO *out,const EVP_PKEY *pkey, int indent,
506 ASN1_PCTX *pctx)
507 {
508 return print_gost_01(out,pkey,indent,pctx,2);
509 }
483 ASN1_PCTX *pctx)
484{
485 return print_gost_01(out, pkey, indent, pctx, 1);
486}
487
488static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
489 ASN1_PCTX *pctx)
490{
491 return print_gost_01(out, pkey, indent, pctx, 2);
492}
493
510/* ---------------------------------------------------------------------*/
494/* ---------------------------------------------------------------------*/
511static int param_missing_gost94(const EVP_PKEY *pk)
512 {
513 const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
514 if (!dsa) return 1;
515 if (!dsa->q) return 1;
516 return 0;
517 }
495static int param_missing_gost94(const EVP_PKEY *pk)
496{
497 const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
498 if (!dsa)
499 return 1;
500 if (!dsa->q)
501 return 1;
502 return 0;
503}
518
504
519static int param_missing_gost01(const EVP_PKEY *pk)
520 {
521 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
522 if (!ec) return 1;
523 if (!EC_KEY_get0_group(ec)) return 1;
524 return 0;
525 }
505static int param_missing_gost01(const EVP_PKEY *pk)
506{
507 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
508 if (!ec)
509 return 1;
510 if (!EC_KEY_get0_group(ec))
511 return 1;
512 return 0;
513}
526
514
527static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
528 {
529 const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
530 DSA *dto = EVP_PKEY_get0(to);
531 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to))
532 {
533 GOSTerr(GOST_F_PARAM_COPY_GOST94,
534 GOST_R_INCOMPATIBLE_ALGORITHMS);
535 return 0;
536 }
537 if (!dfrom)
538 {
539 GOSTerr(GOST_F_PARAM_COPY_GOST94,
540 GOST_R_KEY_PARAMETERS_MISSING);
541 return 0;
542 }
543 if (!dto)
544 {
545 dto = DSA_new();
546 EVP_PKEY_assign(to,EVP_PKEY_base_id(from),dto);
547 }
548#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);
549 COPYBIGNUM(dto,dfrom,p)
550 COPYBIGNUM(dto,dfrom,q)
551 COPYBIGNUM(dto,dfrom,g)
515static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
516{
517 const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
518 DSA *dto = EVP_PKEY_get0(to);
519 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
520 GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS);
521 return 0;
522 }
523 if (!dfrom) {
524 GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING);
525 return 0;
526 }
527 if (!dto) {
528 dto = DSA_new();
529 EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto);
530 }
531#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x);
532 COPYBIGNUM(dto, dfrom, p)
533 COPYBIGNUM(dto, dfrom, q)
534 COPYBIGNUM(dto, dfrom, g)
552
535
553 if (dto->priv_key)
554 gost94_compute_public(dto);
555 return 1;
556 }
557static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
558 {
559 EC_KEY *eto = EVP_PKEY_get0(to);
560 const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
561 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to))
562 {
563 GOSTerr(GOST_F_PARAM_COPY_GOST01,
564 GOST_R_INCOMPATIBLE_ALGORITHMS);
565 return 0;
566 }
567 if (!efrom)
568 {
569 GOSTerr(GOST_F_PARAM_COPY_GOST01,
570 GOST_R_KEY_PARAMETERS_MISSING);
571 return 0;
572 }
573 if (!eto)
574 {
575 eto = EC_KEY_new();
576 EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
577 }
578 EC_KEY_set_group(eto,EC_KEY_get0_group(efrom));
579 if (EC_KEY_get0_private_key(eto))
580 {
581 gost2001_compute_public(eto);
582 }
583 return 1;
584 }
536 if (dto->priv_key)
537 gost94_compute_public(dto);
538 return 1;
539}
585
540
586static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
587 {
588 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
589 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
590 if (!BN_cmp(da->q,db->q)) return 1;
591 return 0;
592 }
541static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
542{
543 EC_KEY *eto = EVP_PKEY_get0(to);
544 const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
545 if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
546 GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS);
547 return 0;
548 }
549 if (!efrom) {
550 GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING);
551 return 0;
552 }
553 if (!eto) {
554 eto = EC_KEY_new();
555 EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto);
556 }
557 EC_KEY_set_group(eto, EC_KEY_get0_group(efrom));
558 if (EC_KEY_get0_private_key(eto)) {
559 gost2001_compute_public(eto);
560 }
561 return 1;
562}
593
563
594static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
595 {
596 if (EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a)))==
597 EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b))))
598 {
599 return 1;
600 }
601 return 0;
564static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
565{
566 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
567 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
568 if (!BN_cmp(da->q, db->q))
569 return 1;
570 return 0;
571}
602
572
603 }
573static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
574{
575 if (EC_GROUP_get_curve_name
576 (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) ==
577 EC_GROUP_get_curve_name(EC_KEY_get0_group
578 (EVP_PKEY_get0((EVP_PKEY *)b)))) {
579 return 1;
580 }
581 return 0;
604
582
583}
584
605/* ---------- Public key functions * --------------------------------------*/
606static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
585/* ---------- Public key functions * --------------------------------------*/
586static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
607 {
608 X509_ALGOR *palg = NULL;
609 const unsigned char *pubkey_buf = NULL;
610 unsigned char *databuf;
611 ASN1_OBJECT *palgobj = NULL;
612 int pub_len,i,j;
613 DSA *dsa;
614 ASN1_OCTET_STRING *octet= NULL;
587{
588 X509_ALGOR *palg = NULL;
589 const unsigned char *pubkey_buf = NULL;
590 unsigned char *databuf;
591 ASN1_OBJECT *palgobj = NULL;
592 int pub_len, i, j;
593 DSA *dsa;
594 ASN1_OCTET_STRING *octet = NULL;
615
595
616 if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
617 &palg, pub)) return 0;
618 EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);
619 if (!decode_gost_algor_params(pk,palg)) return 0;
620 octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
621 if (!octet)
622 {
623 GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE);
624 return 0;
625 }
626 databuf = OPENSSL_malloc(octet->length);
627 for (i=0,j=octet->length-1;i<octet->length;i++,j--)
628 {
629 databuf[j]=octet->data[i];
630 }
631 dsa = EVP_PKEY_get0(pk);
632 dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL);
633 ASN1_OCTET_STRING_free(octet);
634 OPENSSL_free(databuf);
635 return 1;
596 if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
597 return 0;
598 EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
599 if (!decode_gost_algor_params(pk, palg))
600 return 0;
601 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
602 if (!octet) {
603 GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE);
604 return 0;
605 }
606 databuf = OPENSSL_malloc(octet->length);
607 for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
608 databuf[j] = octet->data[i];
609 }
610 dsa = EVP_PKEY_get0(pk);
611 dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL);
612 ASN1_OCTET_STRING_free(octet);
613 OPENSSL_free(databuf);
614 return 1;
636
615
637 }
616}
638
617
639static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
640 {
641 ASN1_OBJECT *algobj = NULL;
642 ASN1_OCTET_STRING *octet = NULL;
643 void *pval = NULL;
644 unsigned char *buf=NULL,*databuf,*sptr;
645 int i,j,data_len,ret=0;
618static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk)
619{
620 ASN1_OBJECT *algobj = NULL;
621 ASN1_OCTET_STRING *octet = NULL;
622 void *pval = NULL;
623 unsigned char *buf = NULL, *databuf, *sptr;
624 int i, j, data_len, ret = 0;
646
625
647 int ptype = V_ASN1_UNDEF;
648 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
649 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
650 if (pk->save_parameters)
651 {
652 ASN1_STRING *params = encode_gost_algor_params(pk);
653 pval = params;
654 ptype = V_ASN1_SEQUENCE;
655 }
656 data_len = BN_num_bytes(dsa->pub_key);
657 databuf = OPENSSL_malloc(data_len);
658 BN_bn2bin(dsa->pub_key,databuf);
659 octet = ASN1_OCTET_STRING_new();
660 ASN1_STRING_set(octet,NULL,data_len);
661 sptr = ASN1_STRING_data(octet);
662 for (i=0,j=data_len-1; i< data_len;i++,j--)
663 {
664 sptr[i]=databuf[j];
665 }
666 OPENSSL_free(databuf);
667 ret = i2d_ASN1_OCTET_STRING(octet,&buf);
668 ASN1_BIT_STRING_free(octet);
669 if (ret <0) return 0;
670 return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
671 }
626 int ptype = V_ASN1_UNDEF;
627 DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
628 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
629 if (pk->save_parameters) {
630 ASN1_STRING *params = encode_gost_algor_params(pk);
631 pval = params;
632 ptype = V_ASN1_SEQUENCE;
633 }
634 data_len = BN_num_bytes(dsa->pub_key);
635 databuf = OPENSSL_malloc(data_len);
636 BN_bn2bin(dsa->pub_key, databuf);
637 octet = ASN1_OCTET_STRING_new();
638 ASN1_STRING_set(octet, NULL, data_len);
639 sptr = ASN1_STRING_data(octet);
640 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
641 sptr[i] = databuf[j];
642 }
643 OPENSSL_free(databuf);
644 ret = i2d_ASN1_OCTET_STRING(octet, &buf);
645 ASN1_BIT_STRING_free(octet);
646 if (ret < 0)
647 return 0;
648 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
649}
672
650
673static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
674 {
675 X509_ALGOR *palg = NULL;
676 const unsigned char *pubkey_buf = NULL;
677 unsigned char *databuf;
678 ASN1_OBJECT *palgobj = NULL;
679 int pub_len,i,j;
680 EC_POINT *pub_key;
681 BIGNUM *X,*Y;
682 ASN1_OCTET_STRING *octet= NULL;
683 int len;
684 const EC_GROUP *group;
651static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub)
652{
653 X509_ALGOR *palg = NULL;
654 const unsigned char *pubkey_buf = NULL;
655 unsigned char *databuf;
656 ASN1_OBJECT *palgobj = NULL;
657 int pub_len, i, j;
658 EC_POINT *pub_key;
659 BIGNUM *X, *Y;
660 ASN1_OCTET_STRING *octet = NULL;
661 int len;
662 const EC_GROUP *group;
685
663
686 if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
687 &palg, pub)) return 0;
688 EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);
689 if (!decode_gost_algor_params(pk,palg)) return 0;
690 group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
691 octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
692 if (!octet)
693 {
694 GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE);
695 return 0;
696 }
697 databuf = OPENSSL_malloc(octet->length);
698 for (i=0,j=octet->length-1;i<octet->length;i++,j--)
699 {
700 databuf[j]=octet->data[i];
701 }
702 len=octet->length/2;
703 ASN1_OCTET_STRING_free(octet);
704
705 Y= getbnfrombuf(databuf,len);
706 X= getbnfrombuf(databuf+len,len);
707 OPENSSL_free(databuf);
708 pub_key = EC_POINT_new(group);
709 if (!EC_POINT_set_affine_coordinates_GFp(group
710 ,pub_key,X,Y,NULL))
711 {
712 GOSTerr(GOST_F_PUB_DECODE_GOST01,
713 ERR_R_EC_LIB);
714 EC_POINT_free(pub_key);
715 BN_free(X);
716 BN_free(Y);
717 return 0;
718 }
719 BN_free(X);
720 BN_free(Y);
721 if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key))
722 {
723 GOSTerr(GOST_F_PUB_DECODE_GOST01,
724 ERR_R_EC_LIB);
725 EC_POINT_free(pub_key);
726 return 0;
727 }
728 EC_POINT_free(pub_key);
729 return 1;
664 if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub))
665 return 0;
666 EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL);
667 if (!decode_gost_algor_params(pk, palg))
668 return 0;
669 group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
670 octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len);
671 if (!octet) {
672 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE);
673 return 0;
674 }
675 databuf = OPENSSL_malloc(octet->length);
676 for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) {
677 databuf[j] = octet->data[i];
678 }
679 len = octet->length / 2;
680 ASN1_OCTET_STRING_free(octet);
730
681
731 }
682 Y = getbnfrombuf(databuf, len);
683 X = getbnfrombuf(databuf + len, len);
684 OPENSSL_free(databuf);
685 pub_key = EC_POINT_new(group);
686 if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) {
687 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
688 EC_POINT_free(pub_key);
689 BN_free(X);
690 BN_free(Y);
691 return 0;
692 }
693 BN_free(X);
694 BN_free(Y);
695 if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) {
696 GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB);
697 EC_POINT_free(pub_key);
698 return 0;
699 }
700 EC_POINT_free(pub_key);
701 return 1;
732
702
733static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
734 {
735 ASN1_OBJECT *algobj = NULL;
736 ASN1_OCTET_STRING *octet = NULL;
737 void *pval = NULL;
738 unsigned char *buf=NULL,*databuf,*sptr;
739 int i,j,data_len,ret=0;
740 const EC_POINT *pub_key;
741 BIGNUM *X,*Y,*order;
742 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
743 int ptype = V_ASN1_UNDEF;
703}
744
704
745 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
746 if (pk->save_parameters)
747 {
748 ASN1_STRING *params = encode_gost_algor_params(pk);
749 pval = params;
750 ptype = V_ASN1_SEQUENCE;
751 }
752 order = BN_new();
753 EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
754 pub_key=EC_KEY_get0_public_key(ec);
755 if (!pub_key)
756 {
757 GOSTerr(GOST_F_PUB_ENCODE_GOST01,
758 GOST_R_PUBLIC_KEY_UNDEFINED);
759 return 0;
760 }
761 X=BN_new();
762 Y=BN_new();
763 EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
764 pub_key,X,Y,NULL);
765 data_len = 2*BN_num_bytes(order);
766 BN_free(order);
767 databuf = OPENSSL_malloc(data_len);
768 memset(databuf,0,data_len);
769
770 store_bignum(X,databuf+data_len/2,data_len/2);
771 store_bignum(Y,databuf,data_len/2);
705static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk)
706{
707 ASN1_OBJECT *algobj = NULL;
708 ASN1_OCTET_STRING *octet = NULL;
709 void *pval = NULL;
710 unsigned char *buf = NULL, *databuf, *sptr;
711 int i, j, data_len, ret = 0;
712 const EC_POINT *pub_key;
713 BIGNUM *X, *Y, *order;
714 const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
715 int ptype = V_ASN1_UNDEF;
772
716
773 BN_free(X);
774 BN_free(Y);
775 octet = ASN1_OCTET_STRING_new();
776 ASN1_STRING_set(octet,NULL,data_len);
777 sptr=ASN1_STRING_data(octet);
778 for (i=0,j=data_len-1;i<data_len;i++,j--)
779 {
780 sptr[i]=databuf[j];
781 }
717 algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
718 if (pk->save_parameters) {
719 ASN1_STRING *params = encode_gost_algor_params(pk);
720 pval = params;
721 ptype = V_ASN1_SEQUENCE;
722 }
723 order = BN_new();
724 EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL);
725 pub_key = EC_KEY_get0_public_key(ec);
726 if (!pub_key) {
727 GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED);
728 return 0;
729 }
730 X = BN_new();
731 Y = BN_new();
732 EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
733 pub_key, X, Y, NULL);
734 data_len = 2 * BN_num_bytes(order);
735 BN_free(order);
736 databuf = OPENSSL_malloc(data_len);
737 memset(databuf, 0, data_len);
738
739 store_bignum(X, databuf + data_len / 2, data_len / 2);
740 store_bignum(Y, databuf, data_len / 2);
741
742 BN_free(X);
743 BN_free(Y);
744 octet = ASN1_OCTET_STRING_new();
745 ASN1_STRING_set(octet, NULL, data_len);
746 sptr = ASN1_STRING_data(octet);
747 for (i = 0, j = data_len - 1; i < data_len; i++, j--) {
748 sptr[i] = databuf[j];
749 }
782 OPENSSL_free(databuf);
750 OPENSSL_free(databuf);
783 ret = i2d_ASN1_OCTET_STRING(octet,&buf);
784 ASN1_BIT_STRING_free(octet);
785 if (ret <0) return 0;
786 return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
787 }
751 ret = i2d_ASN1_OCTET_STRING(octet, &buf);
752 ASN1_BIT_STRING_free(octet);
753 if (ret < 0)
754 return 0;
755 return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret);
756}
788
789static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
757
758static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
790 {
791 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
792 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
793 if (da && db && da->pub_key && db->pub_key
794 && !BN_cmp(da->pub_key,db->pub_key))
795 {
796 return 1;
797 }
798 return 0;
799 }
759{
760 const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
761 const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
762 if (da && db && da->pub_key && db->pub_key
763 && !BN_cmp(da->pub_key, db->pub_key)) {
764 return 1;
765 }
766 return 0;
767}
800
768
801static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b)
802 {
803 const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
804 const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
805 const EC_POINT *ka,*kb;
806 int ret=0;
807 if (!ea || !eb) return 0;
808 ka = EC_KEY_get0_public_key(ea);
809 kb = EC_KEY_get0_public_key(eb);
810 if (!ka || !kb) return 0;
811 ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ;
812 return ret;
813 }
769static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b)
770{
771 const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a);
772 const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
773 const EC_POINT *ka, *kb;
774 int ret = 0;
775 if (!ea || !eb)
776 return 0;
777 ka = EC_KEY_get0_public_key(ea);
778 kb = EC_KEY_get0_public_key(eb);
779 if (!ka || !kb)
780 return 0;
781 ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL));
782 return ret;
783}
814
784
815
816
817
818static int pkey_size_gost(const EVP_PKEY *pk)
785static int pkey_size_gost(const EVP_PKEY *pk)
819 {
820 return 64;
821 }
786{
787 return 64;
788}
822
823static int pkey_bits_gost(const EVP_PKEY *pk)
789
790static int pkey_bits_gost(const EVP_PKEY *pk)
824 {
825 return 256;
826 }
827/*------------------------ ASN1 METHOD for GOST MAC -------------------*/
828static void mackey_free_gost(EVP_PKEY *pk)
829 {
830 if (pk->pkey.ptr) {
831 OPENSSL_free(pk->pkey.ptr);
832 }
833 }
834static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
835{
791{
836 switch (op)
837 {
838 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
839 *(int *)arg2 = NID_id_Gost28147_89_MAC;
840 return 2;
841 }
842 return -2;
843}
792 return 256;
793}
844
794
845static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
795/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/
796static void mackey_free_gost(EVP_PKEY *pk)
846{
797{
847 int nid=gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
848 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
798 if (pk->pkey.ptr) {
799 OPENSSL_free(pk->pkey.ptr);
800 }
849}
801}
850static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
802
803static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2)
851{
804{
852 int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)));
853 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid),pder);
805 switch (op) {
806 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
807 *(int *)arg2 = NID_id_Gost28147_89_MAC;
808 return 2;
809 }
810 return -2;
854}
855
811}
812
856static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen)
813static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
857{
814{
858 ASN1_OBJECT *obj=NULL;
859 DSA *dsa = EVP_PKEY_get0(pkey);
860 int nid;
861 if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
862 return 0;
863 }
864 nid = OBJ_obj2nid(obj);
865 ASN1_OBJECT_free(obj);
866 if (!dsa)
867 {
868 dsa=DSA_new();
869 if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa)) return 0;
870 }
871 if (!fill_GOST94_params(dsa,nid)) return 0;
872 return 1;
873}
815 int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey));
816 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
817}
874
818
875static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) {
876 ASN1_OBJECT *obj=NULL;
877 int nid;
878 EC_KEY *ec = EVP_PKEY_get0(pkey);
879 if (d2i_ASN1_OBJECT(&obj,pder,derlen)==NULL) {
880 return 0;
881 }
882 nid = OBJ_obj2nid(obj);
883 ASN1_OBJECT_free(obj);
884 if (!ec)
885 {
886 ec = EC_KEY_new();
887 if (!EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec)) return 0;
888 }
889 if (!fill_GOST2001_params(ec, nid)) return 0;
890 return 1;
891}
819static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
820{
821 int nid =
822 EC_GROUP_get_curve_name(EC_KEY_get0_group
823 (EVP_PKEY_get0((EVP_PKEY *)pkey)));
824 return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder);
825}
892
826
827static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
828 int derlen)
829{
830 ASN1_OBJECT *obj = NULL;
831 DSA *dsa = EVP_PKEY_get0(pkey);
832 int nid;
833 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
834 return 0;
835 }
836 nid = OBJ_obj2nid(obj);
837 ASN1_OBJECT_free(obj);
838 if (!dsa) {
839 dsa = DSA_new();
840 if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa))
841 return 0;
842 }
843 if (!fill_GOST94_params(dsa, nid))
844 return 0;
845 return 1;
846}
893
847
848static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder,
849 int derlen)
850{
851 ASN1_OBJECT *obj = NULL;
852 int nid;
853 EC_KEY *ec = EVP_PKEY_get0(pkey);
854 if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) {
855 return 0;
856 }
857 nid = OBJ_obj2nid(obj);
858 ASN1_OBJECT_free(obj);
859 if (!ec) {
860 ec = EC_KEY_new();
861 if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec))
862 return 0;
863 }
864 if (!fill_GOST2001_params(ec, nid))
865 return 0;
866 return 1;
867}
894
868
869/* ----------------------------------------------------------------------*/
870int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
871 const char *pemstr, const char *info)
872{
873 *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
874 if (!*ameth)
875 return 0;
876 switch (nid) {
877 case NID_id_GostR3410_94:
878 EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94);
879 EVP_PKEY_asn1_set_private(*ameth,
880 priv_decode_gost, priv_encode_gost,
881 priv_print_gost94);
895
882
883 EVP_PKEY_asn1_set_param(*ameth,
884 gost94_param_decode, gost94_param_encode,
885 param_missing_gost94, param_copy_gost94,
886 param_cmp_gost94, param_print_gost94);
887 EVP_PKEY_asn1_set_public(*ameth,
888 pub_decode_gost94, pub_encode_gost94,
889 pub_cmp_gost94, pub_print_gost94,
890 pkey_size_gost, pkey_bits_gost);
896
891
897/* ----------------------------------------------------------------------*/
898int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info)
899 {
900 *ameth = EVP_PKEY_asn1_new(nid,
901 ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
902 if (!*ameth) return 0;
903 switch (nid)
904 {
905 case NID_id_GostR3410_94:
906 EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
907 EVP_PKEY_asn1_set_private (*ameth,
908 priv_decode_gost, priv_encode_gost,
909 priv_print_gost94);
892 EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
893 break;
894 case NID_id_GostR3410_2001:
895 EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01);
896 EVP_PKEY_asn1_set_private(*ameth,
897 priv_decode_gost, priv_encode_gost,
898 priv_print_gost01);
910
899
911 EVP_PKEY_asn1_set_param (*ameth,
912 gost94_param_decode, gost94_param_encode,
913 param_missing_gost94, param_copy_gost94,
914 param_cmp_gost94,param_print_gost94 );
915 EVP_PKEY_asn1_set_public (*ameth,
916 pub_decode_gost94, pub_encode_gost94,
917 pub_cmp_gost94, pub_print_gost94,
918 pkey_size_gost, pkey_bits_gost);
919
920 EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
921 break;
922 case NID_id_GostR3410_2001:
923 EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost01);
924 EVP_PKEY_asn1_set_private (*ameth,
925 priv_decode_gost, priv_encode_gost,
926 priv_print_gost01);
900 EVP_PKEY_asn1_set_param(*ameth,
901 gost2001_param_decode, gost2001_param_encode,
902 param_missing_gost01, param_copy_gost01,
903 param_cmp_gost01, param_print_gost01);
904 EVP_PKEY_asn1_set_public(*ameth,
905 pub_decode_gost01, pub_encode_gost01,
906 pub_cmp_gost01, pub_print_gost01,
907 pkey_size_gost, pkey_bits_gost);
927
908
928 EVP_PKEY_asn1_set_param (*ameth,
929 gost2001_param_decode, gost2001_param_encode,
930 param_missing_gost01, param_copy_gost01,
931 param_cmp_gost01, param_print_gost01);
932 EVP_PKEY_asn1_set_public (*ameth,
933 pub_decode_gost01, pub_encode_gost01,
934 pub_cmp_gost01, pub_print_gost01,
935 pkey_size_gost, pkey_bits_gost);
936
937 EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost);
938 break;
939 case NID_id_Gost28147_89_MAC:
940 EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
941 EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost);
942 break;
943 }
944 return 1;
945 }
909 EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost);
910 break;
911 case NID_id_Gost28147_89_MAC:
912 EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
913 EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost);
914 break;
915 }
916 return 1;
917}