1 /*
2 * pkcs15-pubkey.c: PKCS #15 public key functions
3 *
4 * Copyright (C) 2002 Juha Yrjölä <juha.yrjola@iki.fi>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <assert.h>
26 #include <fcntl.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #ifdef _WIN32
32 #include <io.h>
33 #else
34 #include <unistd.h>
35 #endif
36
37 #ifdef ENABLE_OPENSSL
38 #include <openssl/bn.h>
39 #include <openssl/rsa.h>
40 #include <openssl/dsa.h>
41 #include <openssl/evp.h>
42 #include <openssl/err.h>
43 #ifndef OPENSSL_NO_EC
44 #include <openssl/ec.h>
45 #endif
46 #endif
47
48 #include "internal.h"
49 #include "asn1.h"
50 #include "pkcs15.h"
51
52
53 #define C_ASN1_PKINFO_ATTR_SIZE 3
54 static const struct sc_asn1_entry c_asn1_pkinfo[C_ASN1_PKINFO_ATTR_SIZE] = {
55 { "algorithm", SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
56 { "subjectPublicKey", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_ALLOC, NULL, NULL},
57 { NULL, 0, 0, 0, NULL, NULL }
58 };
59
60 #define C_ASN1_COM_KEY_ATTR_SIZE 6
61 static const struct sc_asn1_entry c_asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE] = {
62 { "iD", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
63 { "usage", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
64 { "native", SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, SC_ASN1_OPTIONAL, NULL, NULL },
65 { "accessFlags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
66 { "keyReference",SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
67 { NULL, 0, 0, 0, NULL, NULL }
68 };
69
70 #define C_ASN1_COM_PUBKEY_ATTR_SIZE 2
71 static const struct sc_asn1_entry c_asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE] = {
72 { "subjectName", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS,
73 SC_ASN1_EMPTY_ALLOWED | SC_ASN1_ALLOC | SC_ASN1_OPTIONAL, NULL, NULL },
74 { NULL, 0, 0, 0, NULL, NULL }
75 };
76
77 #define C_ASN1_RSAKEY_VALUE_CHOICE_SIZE 3
78 static const struct sc_asn1_entry c_asn1_rsakey_value_choice[C_ASN1_RSAKEY_VALUE_CHOICE_SIZE] = {
79 { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
80 { "direct", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
81 { NULL, 0, 0, 0, NULL, NULL }
82 };
83
84 #define C_ASN1_RSAKEY_ATTR_SIZE 4
85 static const struct sc_asn1_entry c_asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE] = {
86 { "value", SC_ASN1_CHOICE, 0, 0, NULL, NULL },
87 { "modulusLength", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
88 { "keyInfo", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
89 { NULL, 0, 0, 0, NULL, NULL }
90 };
91
92 #define C_ASN1_ECKEY_VALUE_CHOICE_SIZE 3
93 static const struct sc_asn1_entry c_asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_CHOICE_SIZE] = {
94 { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
95 { "direct", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
96 { NULL, 0, 0, 0, NULL, NULL }
97 };
98
99 #define C_ASN1_ECKEY_ATTR_SIZE 3
100 static const struct sc_asn1_entry c_asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE] = {
101 { "value", SC_ASN1_CHOICE, 0, 0, NULL, NULL },
102 { "keyInfo", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
103 { NULL, 0, 0, 0, NULL, NULL }
104 };
105
106 #define C_ASN1_RSA_TYPE_ATTR_SIZE 2
107 static const struct sc_asn1_entry c_asn1_rsa_type_attr[C_ASN1_RSA_TYPE_ATTR_SIZE] = {
108 { "publicRSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
109 { NULL, 0, 0, 0, NULL, NULL }
110 };
111
112 #define C_ASN1_EC_TYPE_ATTR_SIZE 2
113 static const struct sc_asn1_entry c_asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE] = {
114 { "publicECKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
115 { NULL, 0, 0, 0, NULL, NULL }
116 };
117
118 #define C_ASN1_DSAKEY_ATTR_SIZE 2
119 static const struct sc_asn1_entry c_asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE] = {
120 { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
121 { NULL, 0, 0, 0, NULL, NULL }
122 };
123
124 #define C_ASN1_DSA_TYPE_ATTR_SIZE 2
125 static const struct sc_asn1_entry c_asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE] = {
126 { "publicDSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
127 { NULL, 0, 0, 0, NULL, NULL }
128 };
129
130 #define C_ASN1_GOST3410KEY_ATTR_SIZE 5
131 static const struct sc_asn1_entry c_asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE] = {
132 { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
133 { "params_r3410", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
134 { "params_r3411", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
135 { "params_28147", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
136 { NULL, 0, 0, 0, NULL, NULL }
137 };
138
139 #define C_ASN1_GOST3410_TYPE_ATTR_SIZE 2
140 static const struct sc_asn1_entry c_asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYPE_ATTR_SIZE] = {
141 { "publicGOSTR3410KeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
142 { NULL, 0, 0, 0, NULL, NULL }
143 };
144
145 #define C_ASN1_PUBKEY_CHOICE_SIZE 5
146 static const struct sc_asn1_entry c_asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE] = {
147 { "publicRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
148 { "publicDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL },
149 { "publicGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 4 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL },
150 { "publicECKey", SC_ASN1_PKCS15_OBJECT, 0 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL },
151 /*TODO: -DEE not clear EC is needed here as look like it is for pukdf */
152 { NULL, 0, 0, 0, NULL, NULL }
153 };
154
155 #define C_ASN1_PUBKEY_SIZE 2
156 static const struct sc_asn1_entry c_asn1_pubkey[C_ASN1_PUBKEY_SIZE] = {
157 { "publicKey", SC_ASN1_CHOICE, 0, 0, NULL, NULL },
158 { NULL, 0, 0, 0, NULL, NULL }
159 };
160
161 int sc_pkcs15_pubkey_from_spki_sequence(sc_context_t *ctx, const u8 *buf, size_t buflen, sc_pkcs15_pubkey_t ** outpubkey);
162
163 int
sc_pkcs15_decode_pubkey_direct_value(struct sc_pkcs15_card * p15card,struct sc_pkcs15_object * obj)164 sc_pkcs15_decode_pubkey_direct_value(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
165 {
166 struct sc_context *ctx = p15card->card->ctx;
167 struct sc_pkcs15_pubkey_info *info = (struct sc_pkcs15_pubkey_info *) obj->data;
168
169 LOG_FUNC_CALLED(ctx);
170 if (obj->content.value == NULL || obj->content.len == 0)
171 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
172
173 if (*obj->content.value == (SC_ASN1_TAG_CONSTRUCTED | SC_ASN1_TAG_SEQUENCE)) {
174 /* RAW direct value */
175 sc_log(ctx, "Decoding 'RAW' direct value");
176 info->direct.raw.value = malloc(obj->content.len);
177 if (!info->direct.raw.value)
178 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
179 memcpy(info->direct.raw.value, obj->content.value, obj->content.len);
180 info->direct.raw.len = obj->content.len;
181
182 /* TODO: encode 'spki' direct value */
183 }
184
185 if (*obj->content.value == (SC_ASN1_TAG_CONTEXT | SC_ASN1_TAG_CONSTRUCTED | 0x01)) {
186 struct sc_pkcs15_pubkey *pubkey = NULL;
187 int rv;
188
189 /* SPKI direct value */
190 sc_log(ctx, "Decoding 'SPKI' direct value");
191 info->direct.spki.value = malloc(obj->content.len);
192 if (!info->direct.spki.value)
193 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
194 memcpy(info->direct.spki.value, obj->content.value, obj->content.len);
195 info->direct.spki.len = obj->content.len;
196
197 rv = sc_pkcs15_pubkey_from_spki_sequence(ctx, info->direct.spki.value, info->direct.spki.len, &pubkey);
198 LOG_TEST_RET(ctx, rv, "Failed to decode 'SPKI' direct value");
199
200 rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &info->direct.raw.value, &info->direct.raw.len);
201 sc_pkcs15_free_pubkey(pubkey);
202 LOG_TEST_RET(ctx, rv, "Failed to encode 'RAW' direct value");
203 }
204
205 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
206 }
207
208
sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card * p15card,struct sc_pkcs15_object * obj,const u8 ** buf,size_t * buflen)209 int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
210 struct sc_pkcs15_object *obj,
211 const u8 ** buf, size_t *buflen)
212 {
213 struct sc_context *ctx = p15card->card->ctx;
214 struct sc_pkcs15_pubkey_info *info;
215 int r, gostr3410_params[3];
216 struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
217 size_t usage_len, af_len;
218 struct sc_pkcs15_der *der = &obj->content;
219 struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
220 struct sc_asn1_entry asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE];
221 struct sc_asn1_entry asn1_rsakey_value_choice[C_ASN1_RSAKEY_VALUE_CHOICE_SIZE];
222 struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE];
223 struct sc_asn1_entry asn1_rsa_type_attr[C_ASN1_RSA_TYPE_ATTR_SIZE];
224 struct sc_asn1_entry asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_CHOICE_SIZE];
225 struct sc_asn1_entry asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE];
226 struct sc_asn1_entry asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE];
227 struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE];
228 struct sc_asn1_entry asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE];
229 struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE];
230 struct sc_asn1_entry asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYPE_ATTR_SIZE];
231 struct sc_asn1_entry asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE];
232 struct sc_asn1_entry asn1_pubkey[C_ASN1_PUBKEY_SIZE];
233 struct sc_asn1_pkcs15_object rsakey_obj = { obj, asn1_com_key_attr,
234 asn1_com_pubkey_attr, asn1_rsa_type_attr };
235 struct sc_asn1_pkcs15_object eckey_obj = { obj, asn1_com_key_attr,
236 asn1_com_pubkey_attr, asn1_ec_type_attr };
237 struct sc_asn1_pkcs15_object dsakey_obj = { obj, asn1_com_key_attr,
238 asn1_com_pubkey_attr, asn1_dsa_type_attr };
239 struct sc_asn1_pkcs15_object gostr3410key_obj = { obj, asn1_com_key_attr,
240 asn1_com_pubkey_attr, asn1_gostr3410_type_attr };
241
242 info = calloc(1, sizeof *info);
243 if (info == NULL) {
244 r = SC_ERROR_OUT_OF_MEMORY;
245 goto err;
246 }
247 usage_len = sizeof(info->usage);
248 af_len = sizeof(info->access_flags);
249
250 sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey);
251 sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice);
252 sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr);
253 sc_copy_asn1_entry(c_asn1_rsakey_value_choice, asn1_rsakey_value_choice);
254 sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
255 sc_copy_asn1_entry(c_asn1_ec_type_attr, asn1_ec_type_attr);
256 sc_copy_asn1_entry(c_asn1_eckey_value_choice, asn1_eckey_value_choice);
257 sc_copy_asn1_entry(c_asn1_eckey_attr, asn1_eckey_attr);
258 sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr);
259 sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr);
260 sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr);
261 sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
262 sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr);
263 sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
264
265 sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info->subject.value, &info->subject.len, 0);
266
267 sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 0);
268 sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 0);
269 sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 0);
270 sc_format_asn1_entry(asn1_pubkey_choice + 3, &eckey_obj, NULL, 0);
271
272 sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 0);
273
274 sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &info->path, NULL, 0);
275 sc_format_asn1_entry(asn1_rsakey_value_choice + 1, &der->value, &der->len, 0);
276
277 sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 0);
278 sc_format_asn1_entry(asn1_rsakey_attr + 1, &info->modulus_length, NULL, 0);
279
280 sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 0);
281
282 sc_format_asn1_entry(asn1_eckey_value_choice + 0, &info->path, NULL, 0);
283 sc_format_asn1_entry(asn1_eckey_value_choice + 1, &der->value, &der->len, 0);
284
285 sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 0);
286
287 sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 0);
288
289 sc_format_asn1_entry(asn1_dsakey_attr + 0, &info->path, NULL, 0);
290
291 sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 0);
292
293 sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info->path, NULL, 0);
294 sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0);
295 sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0);
296 sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0);
297
298 sc_format_asn1_entry(asn1_com_key_attr + 0, &info->id, NULL, 0);
299 sc_format_asn1_entry(asn1_com_key_attr + 1, &info->usage, &usage_len, 0);
300 sc_format_asn1_entry(asn1_com_key_attr + 2, &info->native, NULL, 0);
301 sc_format_asn1_entry(asn1_com_key_attr + 3, &info->access_flags, &af_len, 0);
302 sc_format_asn1_entry(asn1_com_key_attr + 4, &info->key_reference, NULL, 0);
303
304 sc_format_asn1_entry(asn1_pubkey + 0, asn1_pubkey_choice, NULL, 0);
305
306 /* Fill in defaults */
307 info->key_reference = -1;
308 info->native = 1;
309 memset(gostr3410_params, 0, sizeof(gostr3410_params));
310
311 r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen);
312 if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
313 goto err;
314 LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 decoding failed");
315 if (asn1_pubkey_choice[0].flags & SC_ASN1_PRESENT) {
316 obj->type = SC_PKCS15_TYPE_PUBKEY_RSA;
317 } else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) {
318 obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410;
319 assert(info->modulus_length == 0);
320 info->modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE;
321 assert(info->params.len == 0);
322 info->params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams);
323 info->params.data = malloc(info->params.len);
324 if (info->params.data == NULL) {
325 r = SC_ERROR_OUT_OF_MEMORY;
326 goto err;
327 }
328 assert(sizeof(*keyinfo_gostparams) == info->params.len);
329 keyinfo_gostparams = info->params.data;
330 keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0];
331 keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1];
332 keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2];
333 }
334 else if (asn1_pubkey_choice[3].flags & SC_ASN1_PRESENT) {
335 obj->type = SC_PKCS15_TYPE_PUBKEY_EC;
336 }
337 else {
338 obj->type = SC_PKCS15_TYPE_PUBKEY_DSA;
339 }
340
341 if (!p15card->app || !p15card->app->ddo.aid.len) {
342 if (!p15card->file_app) {
343 r = SC_ERROR_INTERNAL;
344 goto err;
345 }
346 r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info->path);
347 if (r < 0) {
348 goto err;
349 }
350 }
351 else {
352 info->path.aid = p15card->app->ddo.aid;
353 }
354 sc_log(ctx, "PubKey path '%s'", sc_print_path(&info->path));
355
356 /* OpenSC 0.11.4 and older encoded "keyReference" as a negative
357 value. Fixed in 0.11.5 we need to add a hack, so old cards
358 continue to work. */
359 if (info->key_reference < -1)
360 info->key_reference += 256;
361
362 obj->data = info;
363 info = NULL;
364
365 r = sc_pkcs15_decode_pubkey_direct_value(p15card, obj);
366 if (r < 0) {
367 info = obj->data;
368 obj->data = NULL;
369 }
370 LOG_TEST_GOTO_ERR(ctx, r, "Decode public key direct value failed");
371
372 err:
373 if (r < 0) {
374 sc_pkcs15_free_pubkey_info(info);
375 }
376
377 LOG_FUNC_RETURN(ctx, r);
378 }
379
380
381 int
sc_pkcs15_encode_pukdf_entry(struct sc_context * ctx,const struct sc_pkcs15_object * obj,unsigned char ** buf,size_t * buflen)382 sc_pkcs15_encode_pukdf_entry(struct sc_context *ctx, const struct sc_pkcs15_object *obj,
383 unsigned char **buf, size_t *buflen)
384 {
385 struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
386 struct sc_asn1_entry asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE];
387 struct sc_asn1_entry asn1_rsakey_value_choice[C_ASN1_RSAKEY_VALUE_CHOICE_SIZE];
388 struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE];
389 struct sc_asn1_entry asn1_rsa_type_attr[C_ASN1_RSA_TYPE_ATTR_SIZE];
390 struct sc_asn1_entry asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_CHOICE_SIZE];
391 struct sc_asn1_entry asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE];
392 struct sc_asn1_entry asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE];
393 struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE];
394 struct sc_asn1_entry asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE];
395 struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE];
396 struct sc_asn1_entry asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYPE_ATTR_SIZE];
397 struct sc_asn1_entry asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE];
398 struct sc_asn1_entry asn1_pubkey[C_ASN1_PUBKEY_SIZE];
399
400 struct sc_pkcs15_pubkey_info *pubkey = (struct sc_pkcs15_pubkey_info *) obj->data;
401 struct sc_asn1_pkcs15_object rsakey_obj = {
402 (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_rsa_type_attr
403 };
404 struct sc_asn1_pkcs15_object eckey_obj = { (struct sc_pkcs15_object *) obj,
405 asn1_com_key_attr,
406 asn1_com_pubkey_attr, asn1_ec_type_attr };
407 struct sc_asn1_pkcs15_object dsakey_obj = { (struct sc_pkcs15_object *) obj,
408 asn1_com_key_attr,
409 asn1_com_pubkey_attr, asn1_dsa_type_attr };
410 struct sc_asn1_pkcs15_object gostr3410key_obj = { (struct sc_pkcs15_object *) obj,
411 asn1_com_key_attr,
412 asn1_com_pubkey_attr, asn1_gostr3410_type_attr };
413 struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
414 int r;
415 size_t af_len, usage_len;
416 unsigned char *spki_value = NULL;
417
418 sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey);
419 sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice);
420 sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr);
421 sc_copy_asn1_entry(c_asn1_rsakey_value_choice, asn1_rsakey_value_choice);
422 sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
423 sc_copy_asn1_entry(c_asn1_ec_type_attr, asn1_ec_type_attr);
424 sc_copy_asn1_entry(c_asn1_eckey_value_choice, asn1_eckey_value_choice);
425 sc_copy_asn1_entry(c_asn1_eckey_attr, asn1_eckey_attr);
426 sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr);
427 sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr);
428 sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr);
429 sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
430 sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr);
431 sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
432
433 switch (obj->type) {
434 case SC_PKCS15_TYPE_PUBKEY_RSA:
435 sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 1);
436
437 sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 1);
438 if (pubkey->path.len) {
439 sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &pubkey->path, NULL, 1);
440 }
441 else if (pubkey->direct.raw.value && pubkey->direct.raw.len) {
442 /* In RSAPublicKeyChoice 'raw' value keep it's SEQUENCE tag */
443 sc_log(ctx, "Encode direct 'RAW' value");
444 sc_format_asn1_entry(asn1_rsakey_value_choice + 1, pubkey->direct.raw.value, (void *)&pubkey->direct.raw.len, 1);
445 }
446 else if (pubkey->direct.spki.value && pubkey->direct.spki.len) {
447 /* In RSAPublicKeyChoice 'spki' value changes initial SEQUENCE tag for
448 * CONTEXT [1] constructed SEQUENCE */
449 sc_log(ctx, "Encode direct 'SPKI' value");
450 spki_value = malloc(pubkey->direct.spki.len);
451 if (!spki_value)
452 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
453 memcpy(spki_value, pubkey->direct.spki.value, pubkey->direct.spki.len);
454 *spki_value = (SC_ASN1_TAG_CONTEXT | SC_ASN1_TAG_CONSTRUCTED | 0x01);
455
456 sc_format_asn1_entry(asn1_rsakey_value_choice + 1, spki_value, (void *)&pubkey->direct.spki.len, 1);
457 }
458 else if (obj->content.value && obj->content.len) {
459 sc_log(ctx, "Encode 'RAW' object content");
460 sc_format_asn1_entry(asn1_rsakey_value_choice + 1, obj->content.value, (void *)&obj->content.len, 1);
461 }
462 else {
463 sc_log(ctx, "Use empty path");
464 sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &pubkey->path, NULL, 1);
465 }
466
467 sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 1);
468 sc_format_asn1_entry(asn1_rsakey_attr + 1, &pubkey->modulus_length, NULL, 1);
469 break;
470 case SC_PKCS15_TYPE_PUBKEY_DSA:
471 sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 1);
472
473 sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 1);
474
475 sc_format_asn1_entry(asn1_dsakey_attr + 0, &pubkey->path, NULL, 1);
476 break;
477 case SC_PKCS15_TYPE_PUBKEY_GOSTR3410:
478 sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 1);
479
480 sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 1);
481
482 sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &pubkey->path, NULL, 1);
483 if (pubkey->params.len == sizeof(*keyinfo_gostparams)) {
484 keyinfo_gostparams = pubkey->params.data;
485 sc_format_asn1_entry(asn1_gostr3410key_attr + 1,
486 &keyinfo_gostparams->gostr3410, NULL, 1);
487 sc_format_asn1_entry(asn1_gostr3410key_attr + 2,
488 &keyinfo_gostparams->gostr3411, NULL, 1);
489 sc_format_asn1_entry(asn1_gostr3410key_attr + 3,
490 &keyinfo_gostparams->gost28147, NULL, 1);
491 }
492 break;
493 case SC_PKCS15_TYPE_PUBKEY_EC:
494 sc_format_asn1_entry(asn1_pubkey_choice + 3, &eckey_obj, NULL, 1);
495
496 sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 1);
497
498 if (pubkey->path.len) {
499 sc_format_asn1_entry(asn1_eckey_value_choice + 0, &pubkey->path, NULL, 1);
500 }
501 else if (pubkey->direct.spki.value) {
502 sc_format_asn1_entry(asn1_eckey_value_choice + 1, pubkey->direct.spki.value, (void *)&pubkey->direct.spki.len, 1);
503 }
504 else if (pubkey->direct.raw.value) {
505 sc_format_asn1_entry(asn1_eckey_value_choice + 1, pubkey->direct.raw.value, (void *)&pubkey->direct.raw.len, 1);
506 LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "Needs KeyInfo with reference to algorithm in TokenInfo");
507 }
508 else if (obj->content.value) {
509 sc_format_asn1_entry(asn1_eckey_value_choice + 1, obj->content.value, (void *)&obj->content.len, 1);
510 LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "Needs KeyInfo with reference to algorithm in TokenInfo");
511 }
512
513 sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 1);
514
515 break;
516 default:
517 sc_log(ctx, "Unsupported public key type: %X", obj->type);
518 LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
519 break;
520 }
521
522 sc_format_asn1_entry(asn1_com_key_attr + 0, &pubkey->id, NULL, 1);
523 usage_len = sizeof(pubkey->usage);
524 sc_format_asn1_entry(asn1_com_key_attr + 1, &pubkey->usage, &usage_len, 1);
525 if (pubkey->native == 0)
526 sc_format_asn1_entry(asn1_com_key_attr + 2, &pubkey->native, NULL, 1);
527 if (pubkey->access_flags) {
528 af_len = sizeof(pubkey->access_flags);
529 sc_format_asn1_entry(asn1_com_key_attr + 3, &pubkey->access_flags, &af_len, 1);
530 }
531 if (pubkey->key_reference >= 0)
532 sc_format_asn1_entry(asn1_com_key_attr + 4, &pubkey->key_reference, NULL, 1);
533 sc_format_asn1_entry(asn1_pubkey + 0, asn1_pubkey_choice, NULL, 1);
534
535 if (pubkey->subject.value && pubkey->subject.len)
536 sc_format_asn1_entry(asn1_com_pubkey_attr + 0, pubkey->subject.value, &pubkey->subject.len, 1);
537 else
538 memset(asn1_com_pubkey_attr, 0, sizeof(asn1_com_pubkey_attr));
539
540 r = sc_asn1_encode(ctx, asn1_pubkey, buf, buflen);
541
542 sc_log(ctx, "Key path %s", sc_print_path(&pubkey->path));
543
544 if (spki_value)
545 free(spki_value);
546 return r;
547 }
548
549 #define C_ASN1_PUBLIC_KEY_SIZE 2
550 static struct sc_asn1_entry c_asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE] = {
551 { "publicKeyCoefficients", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
552 { NULL, 0, 0, 0, NULL, NULL }
553 };
554
555 #define C_ASN1_RSA_PUB_COEFFICIENTS_SIZE 3
556 static struct sc_asn1_entry c_asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIENTS_SIZE] = {
557 { "modulus", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
558 { "exponent", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
559 { NULL, 0, 0, 0, NULL, NULL }
560 };
561
562 #define C_ASN1_DSA_PUB_COEFFICIENTS_SIZE 5
563 static struct sc_asn1_entry c_asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE] = {
564 { "publicKey",SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
565 { "paramP", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
566 { "paramQ", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
567 { "paramG", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
568 { NULL, 0, 0, 0, NULL, NULL },
569 };
570
571 #define C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE 2
572 static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE] = {
573 { "xy", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL },
574 { NULL, 0, 0, 0, NULL, NULL }
575 };
576
577 #define C_ASN1_EC_POINTQ_SIZE 2
578 static struct sc_asn1_entry c_asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE] = {
579 { "ecpointQ", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL },
580 { NULL, 0, 0, 0, NULL, NULL }
581 };
582
583 #define C_ASN1_EDDSA_PUBKEY_SIZE 2
584 static struct sc_asn1_entry c_asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE] = {
585 { "pubkey", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL },
586 { NULL, 0, 0, 0, NULL, NULL }
587 };
588
589
590 int
sc_pkcs15_decode_pubkey_rsa(sc_context_t * ctx,struct sc_pkcs15_pubkey_rsa * key,const u8 * buf,size_t buflen)591 sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key,
592 const u8 *buf, size_t buflen)
593 {
594 struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE];
595 struct sc_asn1_entry asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIENTS_SIZE];
596 int r;
597
598 LOG_FUNC_CALLED(ctx);
599 sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
600 sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_pub_coefficients, NULL, 0);
601
602 sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_pub_coefficients);
603 sc_format_asn1_entry(asn1_rsa_pub_coefficients + 0, &key->modulus.data, &key->modulus.len, 0);
604 sc_format_asn1_entry(asn1_rsa_pub_coefficients + 1, &key->exponent.data, &key->exponent.len, 0);
605
606 r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL);
607 LOG_TEST_RET(ctx, r, "ASN.1 parsing of public key failed");
608
609 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
610 }
611
612
613 int
sc_pkcs15_encode_pubkey_rsa(sc_context_t * ctx,struct sc_pkcs15_pubkey_rsa * key,u8 ** buf,size_t * buflen)614 sc_pkcs15_encode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key,
615 u8 **buf, size_t *buflen)
616 {
617 struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE];
618 struct sc_asn1_entry asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIENTS_SIZE];
619 int r;
620
621 LOG_FUNC_CALLED(ctx);
622 sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
623 sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_pub_coefficients, NULL, 1);
624
625 sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_pub_coefficients);
626 sc_format_asn1_entry(asn1_rsa_pub_coefficients + 0, key->modulus.data, &key->modulus.len, 1);
627 sc_format_asn1_entry(asn1_rsa_pub_coefficients + 1, key->exponent.data, &key->exponent.len, 1);
628
629 r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen);
630 LOG_TEST_RET(ctx, r, "ASN.1 encoding failed");
631
632 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
633 }
634
635
636 int
sc_pkcs15_decode_pubkey_dsa(sc_context_t * ctx,struct sc_pkcs15_pubkey_dsa * key,const u8 * buf,size_t buflen)637 sc_pkcs15_decode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key,
638 const u8 *buf, size_t buflen)
639 {
640 struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE];
641 struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE];
642 int r;
643
644 LOG_FUNC_CALLED(ctx);
645 sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
646 sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coefficients);
647
648 sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coefficients, NULL, 1);
649 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 0, &key->pub.data, &key->pub.len, 0);
650 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 1, &key->g.data, &key->g.len, 0);
651 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 2, &key->p.data, &key->p.len, 0);
652 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 3, &key->q.data, &key->q.len, 0);
653
654 r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL);
655 LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
656
657 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
658 }
659
660
661 int
sc_pkcs15_encode_pubkey_dsa(sc_context_t * ctx,struct sc_pkcs15_pubkey_dsa * key,u8 ** buf,size_t * buflen)662 sc_pkcs15_encode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key,
663 u8 **buf, size_t *buflen)
664 {
665 struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE];
666 struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE];
667 int r;
668
669 LOG_FUNC_CALLED(ctx);
670 sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
671 sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coefficients);
672
673 sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coefficients, NULL, 1);
674 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 0, key->pub.data, &key->pub.len, 1);
675 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 1, key->g.data, &key->g.len, 1);
676 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 2, key->p.data, &key->p.len, 1);
677 sc_format_asn1_entry(asn1_dsa_pub_coefficients + 3, key->q.data, &key->q.len, 1);
678
679 r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen);
680 LOG_TEST_RET(ctx, r, "ASN.1 encoding failed");
681
682 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
683 }
684
685
686 int
sc_pkcs15_decode_pubkey_gostr3410(sc_context_t * ctx,struct sc_pkcs15_pubkey_gostr3410 * key,const u8 * buf,size_t buflen)687 sc_pkcs15_decode_pubkey_gostr3410(sc_context_t *ctx, struct sc_pkcs15_pubkey_gostr3410 *key,
688 const u8 *buf, size_t buflen)
689 {
690 struct sc_asn1_entry asn1_gostr3410_pub_coeff[C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE];
691 int r;
692 struct sc_object_id param_key = {{ 1, 2, 643, 2, 2, 35, 1, -1}};
693 struct sc_object_id param_hash = {{ 1, 2, 643, 2, 2, 30, 1, -1}};
694
695 LOG_FUNC_CALLED(ctx);
696 sc_copy_asn1_entry(c_asn1_gostr3410_pub_coefficients, asn1_gostr3410_pub_coeff);
697 sc_format_asn1_entry(asn1_gostr3410_pub_coeff + 0, &key->xy.data, &key->xy.len, 0);
698
699 r = sc_asn1_decode(ctx, asn1_gostr3410_pub_coeff, buf, buflen, NULL, NULL);
700 LOG_TEST_RET(ctx, r, "ASN.1 parsing of public key failed");
701
702 key->params.key = param_key;
703 key->params.hash = param_hash;
704
705 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
706 }
707
708 int
sc_pkcs15_encode_pubkey_gostr3410(sc_context_t * ctx,struct sc_pkcs15_pubkey_gostr3410 * key,u8 ** buf,size_t * buflen)709 sc_pkcs15_encode_pubkey_gostr3410(sc_context_t *ctx,
710 struct sc_pkcs15_pubkey_gostr3410 *key,
711 u8 **buf, size_t *buflen)
712 {
713 struct sc_asn1_entry asn1_gostr3410_pub_coeff[C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE];
714 int r;
715
716 LOG_FUNC_CALLED(ctx);
717 sc_copy_asn1_entry(c_asn1_gostr3410_pub_coefficients, asn1_gostr3410_pub_coeff);
718 sc_format_asn1_entry(asn1_gostr3410_pub_coeff + 0, key->xy.data, &key->xy.len, 1);
719
720 r = sc_asn1_encode(ctx, asn1_gostr3410_pub_coeff, buf, buflen);
721 LOG_TEST_RET(ctx, r, "ASN.1 encoding failed");
722
723 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
724 }
725
726 /*
727 * We are storing the ec_pointQ as u8 string. not as DER
728 */
729 int
sc_pkcs15_decode_pubkey_ec(sc_context_t * ctx,struct sc_pkcs15_pubkey_ec * key,const u8 * buf,size_t buflen)730 sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx,
731 struct sc_pkcs15_pubkey_ec *key,
732 const u8 *buf, size_t buflen)
733 {
734 int r;
735 u8 * ecpoint_data;
736 size_t ecpoint_len;
737 struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE];
738
739 LOG_FUNC_CALLED(ctx);
740 sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
741 sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1);
742 r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL);
743 if (r < 0)
744 LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
745
746 if (*ecpoint_data != 0x04)
747 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Supported only uncompressed EC pointQ value");
748
749 key->ecpointQ.len = ecpoint_len;
750 key->ecpointQ.value = ecpoint_data;
751
752 /*
753 * Only get here if raw point is stored in pkcs15 without curve name
754 * spki has the curvename, so we can get the field_length
755 * Following only true for curves that are multiple of 8
756 */
757 key->params.field_length = (ecpoint_len - 1)/2 * 8;
758 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
759 }
760
761
762 int
sc_pkcs15_encode_pubkey_ec(sc_context_t * ctx,struct sc_pkcs15_pubkey_ec * key,u8 ** buf,size_t * buflen)763 sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key,
764 u8 **buf, size_t *buflen)
765 {
766 struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE];
767
768 LOG_FUNC_CALLED(ctx);
769 sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
770 sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key->ecpointQ.len, 1);
771
772 LOG_FUNC_RETURN(ctx,
773 sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen));
774 }
775
776 /*
777 * EdDSA keys are just byte strings. For now only
778 * for Ed25519 keys 32B length are supported
779 */
780 int
sc_pkcs15_decode_pubkey_eddsa(sc_context_t * ctx,struct sc_pkcs15_pubkey_eddsa * key,const u8 * buf,size_t buflen)781 sc_pkcs15_decode_pubkey_eddsa(sc_context_t *ctx,
782 struct sc_pkcs15_pubkey_eddsa *key,
783 const u8 *buf, size_t buflen)
784 {
785 int r;
786 u8 * pubkey = NULL;
787 size_t pubkey_len;
788 struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE];
789
790 LOG_FUNC_CALLED(ctx);
791 sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey);
792 sc_format_asn1_entry(asn1_eddsa_pubkey + 0, &pubkey, &pubkey_len, 1);
793 r = sc_asn1_decode(ctx, asn1_eddsa_pubkey, buf, buflen, NULL, NULL);
794 if (r < 0)
795 LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
796
797 key->pubkey.len = pubkey_len;
798 key->pubkey.value = pubkey;
799
800 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
801 }
802
803 int
sc_pkcs15_encode_pubkey_eddsa(sc_context_t * ctx,struct sc_pkcs15_pubkey_eddsa * key,u8 ** buf,size_t * buflen)804 sc_pkcs15_encode_pubkey_eddsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_eddsa *key,
805 u8 **buf, size_t *buflen)
806 {
807 struct sc_asn1_entry asn1_eddsa_pubkey[C_ASN1_EDDSA_PUBKEY_SIZE];
808
809 LOG_FUNC_CALLED(ctx);
810 sc_copy_asn1_entry(c_asn1_eddsa_pubkey, asn1_eddsa_pubkey);
811 sc_format_asn1_entry(asn1_eddsa_pubkey + 0, key->pubkey.value, &key->pubkey.len, 1);
812
813 LOG_FUNC_RETURN(ctx,
814 sc_asn1_encode(ctx, asn1_eddsa_pubkey, buf, buflen));
815 }
816
817
818 int
sc_pkcs15_encode_pubkey(sc_context_t * ctx,struct sc_pkcs15_pubkey * key,u8 ** buf,size_t * len)819 sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
820 u8 **buf, size_t *len)
821 {
822 if (key->algorithm == SC_ALGORITHM_RSA)
823 return sc_pkcs15_encode_pubkey_rsa(ctx, &key->u.rsa, buf, len);
824 if (key->algorithm == SC_ALGORITHM_DSA)
825 return sc_pkcs15_encode_pubkey_dsa(ctx, &key->u.dsa, buf, len);
826 if (key->algorithm == SC_ALGORITHM_GOSTR3410)
827 return sc_pkcs15_encode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len);
828 if (key->algorithm == SC_ALGORITHM_EC)
829 return sc_pkcs15_encode_pubkey_ec(ctx, &key->u.ec, buf, len);
830 if (key->algorithm == SC_ALGORITHM_EDDSA ||
831 key->algorithm == SC_ALGORITHM_XEDDSA) /* XXX encoding is the same here */
832 return sc_pkcs15_encode_pubkey_eddsa(ctx, &key->u.eddsa, buf, len);
833
834 sc_log(ctx, "Encoding of public key type %u not supported", key->algorithm);
835 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
836 }
837
838
839 static const struct sc_asn1_entry c_asn1_spki_key_items[] = {
840 { "algorithm", SC_ASN1_ALGORITHM_ID, SC_ASN1_CONS| SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL},
841 { "key", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
842 { NULL, 0, 0, 0, NULL, NULL }
843 };
844
845 static const struct sc_asn1_entry c_asn1_spki_key[] = {
846 { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL},
847 { NULL, 0, 0, 0, NULL, NULL }
848 };
849
850 /*
851 * Encode a pubkey as a SPKI, useful for pkcs15-tool, and for PKCS#15 files.
852 */
853 int
sc_pkcs15_encode_pubkey_as_spki(sc_context_t * ctx,struct sc_pkcs15_pubkey * pubkey,u8 ** buf,size_t * len)854 sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubkey,
855 u8 **buf, size_t *len)
856 {
857 int r = 0;
858 struct sc_asn1_entry asn1_spki_key[2], asn1_spki_key_items[3];
859 struct sc_pkcs15_u8 pkey;
860 size_t key_len;
861
862 LOG_FUNC_CALLED(ctx);
863 pkey.value = NULL;
864 pkey.len = 0;
865
866 sc_log(ctx, "Encoding public key with algorithm %i", pubkey->algorithm);
867 if (!pubkey->alg_id) {
868 pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id));
869 if (!pubkey->alg_id)
870 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
871
872 sc_init_oid(&pubkey->alg_id->oid);
873 pubkey->alg_id->algorithm = pubkey->algorithm;
874 }
875
876 switch (pubkey->algorithm) {
877 case SC_ALGORITHM_EC:
878 /*
879 * most keys, but not EC have only one encoding.
880 * For a SPKI, the ecpoint is placed directly in the
881 * BIT STRING
882 */
883 key_len = pubkey->u.ec.ecpointQ.len * 8;
884 pkey.value = pubkey->u.ec.ecpointQ.value;
885 pkey.len = 0; /* flag as do not delete */
886
887 if (pubkey->u.ec.params.named_curve || pubkey->u.ec.params.der.value) {
888 struct sc_ec_parameters *ec_params = NULL;
889
890 r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
891 LOG_TEST_RET(ctx, r, "failed to fix EC parameters");
892
893 ec_params = calloc(1, sizeof(struct sc_ec_parameters));
894 if (!ec_params)
895 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
896 ec_params->type = 1;
897 ec_params->der.value = calloc(pubkey->u.ec.params.der.len, 1);
898 if (!ec_params->der.value) {
899 free(ec_params);
900 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
901 }
902 memcpy(ec_params->der.value, pubkey->u.ec.params.der.value, pubkey->u.ec.params.der.len);
903 ec_params->der.len = pubkey->u.ec.params.der.len;
904 /* This could have been already allocated: avoid memory leak */
905 sc_asn1_clear_algorithm_id(pubkey->alg_id);
906 pubkey->alg_id->params = ec_params;
907 }
908 break;
909 case SC_ALGORITHM_GOSTR3410:
910 /* TODO is this needed? does it cause mem leak? */
911 pubkey->alg_id->params = &pubkey->u.gostr3410.params;
912 r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len);
913 key_len = pkey.len * 8;
914 break;
915 case SC_ALGORITHM_EDDSA:
916 case SC_ALGORITHM_XEDDSA:
917 /* For a SPKI, the pubkey is placed directly in the BIT STRING */
918 pkey.value = malloc(pubkey->u.eddsa.pubkey.len);
919 memcpy(pkey.value, pubkey->u.eddsa.pubkey.value, pubkey->u.eddsa.pubkey.len);
920 // Should be pkey.len = 0 there?
921 key_len = pubkey->u.eddsa.pubkey.len * 8;
922 break;
923 default:
924 r = sc_pkcs15_encode_pubkey(ctx, pubkey, &pkey.value, &pkey.len);
925 key_len = pkey.len * 8;
926 break;
927 }
928
929 if (r == 0) {
930 sc_copy_asn1_entry(c_asn1_spki_key, asn1_spki_key);
931 sc_copy_asn1_entry(c_asn1_spki_key_items, asn1_spki_key_items);
932 sc_format_asn1_entry(asn1_spki_key + 0, asn1_spki_key_items, NULL, 1);
933 sc_format_asn1_entry(asn1_spki_key_items + 0, pubkey->alg_id, NULL, 1);
934 sc_format_asn1_entry(asn1_spki_key_items + 1, pkey.value, &key_len, 1);
935
936 r = sc_asn1_encode(ctx, asn1_spki_key, buf, len);
937 }
938
939 if (pkey.len && pkey.value)
940 free(pkey.value);
941
942 LOG_FUNC_RETURN(ctx, r);
943 }
944
945
946 int
sc_pkcs15_decode_pubkey(sc_context_t * ctx,struct sc_pkcs15_pubkey * key,const u8 * buf,size_t len)947 sc_pkcs15_decode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
948 const u8 *buf, size_t len)
949 {
950 if (key->algorithm == SC_ALGORITHM_RSA)
951 return sc_pkcs15_decode_pubkey_rsa(ctx, &key->u.rsa, buf, len);
952 if (key->algorithm == SC_ALGORITHM_DSA)
953 return sc_pkcs15_decode_pubkey_dsa(ctx, &key->u.dsa, buf, len);
954 if (key->algorithm == SC_ALGORITHM_GOSTR3410)
955 return sc_pkcs15_decode_pubkey_gostr3410(ctx, &key->u.gostr3410, buf, len);
956 if (key->algorithm == SC_ALGORITHM_EC)
957 return sc_pkcs15_decode_pubkey_ec(ctx, &key->u.ec, buf, len);
958 if (key->algorithm == SC_ALGORITHM_EDDSA ||
959 key->algorithm == SC_ALGORITHM_XEDDSA)
960 return sc_pkcs15_decode_pubkey_eddsa(ctx, &key->u.eddsa, buf, len);
961
962 sc_log(ctx, "Decoding of public key type %u not supported", key->algorithm);
963 return SC_ERROR_NOT_SUPPORTED;
964 }
965
966
967 /*
968 * Read public key.
969 */
970 int
sc_pkcs15_read_pubkey(struct sc_pkcs15_card * p15card,const struct sc_pkcs15_object * obj,struct sc_pkcs15_pubkey ** out)971 sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
972 struct sc_pkcs15_pubkey **out)
973 {
974 struct sc_context *ctx;
975 const struct sc_pkcs15_pubkey_info *info = NULL;
976 struct sc_pkcs15_pubkey *pubkey = NULL;
977 unsigned char *data = NULL;
978 size_t len;
979 int algorithm, r;
980
981 if (p15card == NULL || p15card->card == NULL || p15card->card->ops == NULL
982 || obj == NULL || out == NULL) {
983 return SC_ERROR_INVALID_ARGUMENTS;
984 }
985 ctx = p15card->card->ctx;
986
987 LOG_FUNC_CALLED(ctx);
988 sc_log(ctx, "Public key type 0x%X", obj->type);
989
990 switch (obj->type) {
991 case SC_PKCS15_TYPE_PUBKEY_RSA:
992 algorithm = SC_ALGORITHM_RSA;
993 break;
994 case SC_PKCS15_TYPE_PUBKEY_DSA:
995 algorithm = SC_ALGORITHM_DSA;
996 break;
997 case SC_PKCS15_TYPE_PUBKEY_GOSTR3410:
998 algorithm = SC_ALGORITHM_GOSTR3410;
999 break;
1000 case SC_PKCS15_TYPE_PUBKEY_EC:
1001 algorithm = SC_ALGORITHM_EC;
1002 break;
1003 case SC_PKCS15_TYPE_PUBKEY_EDDSA:
1004 algorithm = SC_ALGORITHM_EDDSA;
1005 break;
1006 case SC_PKCS15_TYPE_PUBKEY_XEDDSA:
1007 algorithm = SC_ALGORITHM_XEDDSA;
1008 break;
1009 default:
1010 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported public key type.");
1011 }
1012 info = (const struct sc_pkcs15_pubkey_info *) obj->data;
1013
1014 pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey));
1015 if (pubkey == NULL) {
1016 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1017 }
1018 pubkey->algorithm = algorithm;
1019
1020 /* starting from SPKI direct value
1021 in a compact form it presents complete public key data */
1022 if (info->direct.spki.value && info->direct.spki.len) {
1023 sc_log(ctx, "Using direct SPKI value, tag 0x%X", *(info->direct.spki.value));
1024 r = sc_pkcs15_pubkey_from_spki_sequence(ctx, info->direct.spki.value, info->direct.spki.len, &pubkey);
1025 LOG_TEST_GOTO_ERR(ctx, r, "Failed to decode 'SPKI' direct value");
1026 }
1027 else if (info->direct.raw.value && info->direct.raw.len) {
1028 sc_log(ctx, "Using direct RAW value");
1029 r = sc_pkcs15_decode_pubkey(ctx, pubkey, info->direct.raw.value, info->direct.raw.len);
1030 LOG_TEST_GOTO_ERR(ctx, r, "Failed to decode 'RAW' direct value");
1031 sc_log(ctx, "TODO: for EC keys 'raw' data needs to be completed with referenced algorithm from TokenInfo");
1032 }
1033 else if (obj->content.value && obj->content.len) {
1034 sc_log(ctx, "Using object content");
1035 r = sc_pkcs15_decode_pubkey(ctx, pubkey, obj->content.value, obj->content.len);
1036 LOG_TEST_GOTO_ERR(ctx, r, "Failed to decode object content value");
1037 sc_log(ctx, "TODO: for EC keys 'raw' data needs to be completed with referenced algorithm from TokenInfo");
1038 }
1039 else if (p15card->card->ops->read_public_key) {
1040 sc_log(ctx, "Call card specific 'read-public-key' handle");
1041 r = p15card->card->ops->read_public_key(p15card->card, algorithm,
1042 (struct sc_path *)&info->path, info->key_reference, info->modulus_length,
1043 &data, &len);
1044 LOG_TEST_GOTO_ERR(ctx, r, "Card specific 'read-public' procedure failed.");
1045
1046 r = sc_pkcs15_decode_pubkey(ctx, pubkey, data, len);
1047 LOG_TEST_GOTO_ERR(ctx, r, "Decode public key error");
1048 }
1049 else if (info->path.len) {
1050 sc_log(ctx, "Read from EF and decode");
1051 r = sc_pkcs15_read_file(p15card, &info->path, &data, &len);
1052 LOG_TEST_GOTO_ERR(ctx, r, "Failed to read public key file.");
1053
1054 if ((algorithm == SC_ALGORITHM_EC || algorithm == SC_ALGORITHM_EDDSA || algorithm == SC_ALGORITHM_XEDDSA)
1055 && *data == (SC_ASN1_TAG_SEQUENCE | SC_ASN1_TAG_CONSTRUCTED))
1056 r = sc_pkcs15_pubkey_from_spki_sequence(ctx, data, len, &pubkey);
1057 else
1058 r = sc_pkcs15_decode_pubkey(ctx, pubkey, data, len);
1059 LOG_TEST_GOTO_ERR(ctx, r, "Decode public key error");
1060 }
1061 else {
1062 r = SC_ERROR_NOT_IMPLEMENTED;
1063 LOG_TEST_GOTO_ERR(ctx, r, "No way to get public key");
1064 }
1065
1066 err:
1067 if (r) {
1068 sc_pkcs15_free_pubkey(pubkey);
1069 } else
1070 *out = pubkey;
1071 free(data);
1072
1073 LOG_FUNC_RETURN(ctx, r);
1074 }
1075
1076
1077 static int
sc_pkcs15_dup_bignum(struct sc_pkcs15_bignum * dst,struct sc_pkcs15_bignum * src)1078 sc_pkcs15_dup_bignum (struct sc_pkcs15_bignum *dst, struct sc_pkcs15_bignum *src)
1079 {
1080 if (!dst || !src) {
1081 return SC_ERROR_INVALID_ARGUMENTS;
1082 }
1083
1084 if (src->data && src->len) {
1085 dst->data = calloc(1, src->len);
1086 if (!dst->data)
1087 return SC_ERROR_OUT_OF_MEMORY;
1088 memcpy(dst->data, src->data, src->len);
1089 dst->len = src->len;
1090 }
1091
1092 return 0;
1093 }
1094
1095
1096 int
sc_pkcs15_pubkey_from_prvkey(struct sc_context * ctx,struct sc_pkcs15_prkey * prvkey,struct sc_pkcs15_pubkey ** out)1097 sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, struct sc_pkcs15_prkey *prvkey,
1098 struct sc_pkcs15_pubkey **out)
1099 {
1100 struct sc_pkcs15_pubkey *pubkey = NULL;
1101 int rv = SC_SUCCESS;
1102
1103 if (!prvkey || !out) {
1104 return SC_ERROR_INVALID_ARGUMENTS;
1105 }
1106
1107 *out = NULL;
1108 pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey));
1109 if (!pubkey)
1110 return SC_ERROR_OUT_OF_MEMORY;
1111
1112 pubkey->algorithm = prvkey->algorithm;
1113 switch (prvkey->algorithm) {
1114 case SC_ALGORITHM_RSA:
1115 rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.modulus, &prvkey->u.rsa.modulus);
1116 if (!rv)
1117 rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &prvkey->u.rsa.exponent);
1118 break;
1119 case SC_ALGORITHM_DSA:
1120 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &prvkey->u.dsa.pub);
1121 if (!rv)
1122 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &prvkey->u.dsa.p);
1123 if (!rv)
1124 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &prvkey->u.dsa.q);
1125 if (!rv)
1126 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &prvkey->u.dsa.g);
1127 break;
1128 case SC_ALGORITHM_GOSTR3410:
1129 break;
1130 case SC_ALGORITHM_EC:
1131 pubkey->u.ec.ecpointQ.value = malloc(prvkey->u.ec.ecpointQ.len);
1132 if (!pubkey->u.ec.ecpointQ.value) {
1133 sc_pkcs15_free_pubkey(pubkey);
1134 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1135 }
1136 memcpy(pubkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.value, prvkey->u.ec.ecpointQ.len);
1137 pubkey->u.ec.ecpointQ.len = prvkey->u.ec.ecpointQ.len;
1138 break;
1139 case SC_ALGORITHM_EDDSA:
1140 case SC_ALGORITHM_XEDDSA:
1141 /* Copy pubkey */
1142 if (prvkey->u.eddsa.pubkey.value == NULL || prvkey->u.eddsa.pubkey.len <= 0) {
1143 sc_pkcs15_free_pubkey(pubkey);
1144 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
1145 }
1146 pubkey->u.eddsa.pubkey.value = malloc(prvkey->u.eddsa.pubkey.len);
1147 if (!pubkey->u.eddsa.pubkey.value) {
1148 sc_pkcs15_free_pubkey(pubkey);
1149 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1150 }
1151 memcpy(pubkey->u.eddsa.pubkey.value, prvkey->u.eddsa.pubkey.value, prvkey->u.eddsa.pubkey.len);
1152 pubkey->u.eddsa.pubkey.len = prvkey->u.eddsa.pubkey.len;
1153
1154 break;
1155 default:
1156 sc_log(ctx, "Unsupported private key algorithm");
1157 rv = SC_ERROR_NOT_SUPPORTED;
1158 }
1159
1160 if (rv)
1161 sc_pkcs15_free_pubkey(pubkey);
1162 else
1163 *out = pubkey;
1164
1165 return rv;
1166 }
1167
1168
1169 int
sc_pkcs15_dup_pubkey(struct sc_context * ctx,struct sc_pkcs15_pubkey * key,struct sc_pkcs15_pubkey ** out)1170 sc_pkcs15_dup_pubkey(struct sc_context *ctx, struct sc_pkcs15_pubkey *key, struct sc_pkcs15_pubkey **out)
1171 {
1172 struct sc_pkcs15_pubkey *pubkey = NULL;
1173 int rv = SC_SUCCESS;
1174 u8* alg;
1175 size_t alglen;
1176
1177 LOG_FUNC_CALLED(ctx);
1178
1179 if (!key || !out) {
1180 return SC_ERROR_INVALID_ARGUMENTS;
1181 }
1182
1183 *out = NULL;
1184 pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey));
1185 if (!pubkey)
1186 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1187
1188 pubkey->algorithm = key->algorithm;
1189
1190 if (key->alg_id) {
1191 rv = sc_asn1_encode_algorithm_id(ctx, &alg, &alglen,key->alg_id, 0);
1192 if (rv == SC_SUCCESS) {
1193 pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id));
1194 if (pubkey->alg_id == NULL) {
1195 free(pubkey);
1196 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1197 }
1198 rv = sc_asn1_decode_algorithm_id(ctx, alg, alglen, pubkey->alg_id, 0);
1199 free(alg);
1200 }
1201 }
1202
1203 switch (key->algorithm) {
1204 case SC_ALGORITHM_RSA:
1205 rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.modulus, &key->u.rsa.modulus);
1206 if (!rv)
1207 rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &key->u.rsa.exponent);
1208 break;
1209 case SC_ALGORITHM_DSA:
1210 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &key->u.dsa.pub);
1211 if (!rv)
1212 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &key->u.dsa.p);
1213 if (!rv)
1214 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &key->u.dsa.q);
1215 if (!rv)
1216 rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &key->u.dsa.g);
1217 break;
1218 case SC_ALGORITHM_GOSTR3410:
1219 break;
1220 case SC_ALGORITHM_EC:
1221 pubkey->u.ec.ecpointQ.value = malloc(key->u.ec.ecpointQ.len);
1222 if (!pubkey->u.ec.ecpointQ.value) {
1223 rv = SC_ERROR_OUT_OF_MEMORY;
1224 break;
1225 }
1226 memcpy(pubkey->u.ec.ecpointQ.value, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len);
1227 pubkey->u.ec.ecpointQ.len = key->u.ec.ecpointQ.len;
1228
1229 pubkey->u.ec.params.der.value = malloc(key->u.ec.params.der.len);
1230 if (!pubkey->u.ec.params.der.value) {
1231 rv = SC_ERROR_OUT_OF_MEMORY;
1232 break;
1233 }
1234 memcpy(pubkey->u.ec.params.der.value, key->u.ec.params.der.value, key->u.ec.params.der.len);
1235 pubkey->u.ec.params.der.len = key->u.ec.params.der.len;
1236
1237 if (key->u.ec.params.named_curve){
1238 pubkey->u.ec.params.named_curve = strdup(key->u.ec.params.named_curve);
1239 if (!pubkey->u.ec.params.named_curve)
1240 rv = SC_ERROR_OUT_OF_MEMORY;
1241 }
1242 else {
1243 sc_log(ctx, "named_curve parameter missing");
1244 rv = SC_ERROR_NOT_SUPPORTED;
1245 }
1246
1247 break;
1248 case SC_ALGORITHM_EDDSA:
1249 case SC_ALGORITHM_XEDDSA:
1250 /* Copy pubkey */
1251 pubkey->u.eddsa.pubkey.value = malloc(key->u.eddsa.pubkey.len);
1252 if (!pubkey->u.eddsa.pubkey.value) {
1253 rv = SC_ERROR_OUT_OF_MEMORY;
1254 break;
1255 }
1256 memcpy(pubkey->u.eddsa.pubkey.value, key->u.eddsa.pubkey.value, key->u.eddsa.pubkey.len);
1257 pubkey->u.eddsa.pubkey.len = key->u.eddsa.pubkey.len;
1258
1259 break;
1260 default:
1261 sc_log(ctx, "Unsupported private key algorithm");
1262 rv = SC_ERROR_NOT_SUPPORTED;
1263 }
1264
1265 if (rv)
1266 sc_pkcs15_free_pubkey(pubkey);
1267 else
1268 *out = pubkey;
1269
1270 LOG_FUNC_RETURN(ctx, rv);
1271 }
1272
1273
1274
1275 void
sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey * key)1276 sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
1277 {
1278 if (key == NULL) {
1279 return;
1280 }
1281 if (key->alg_id) {
1282 sc_asn1_clear_algorithm_id(key->alg_id);
1283 free(key->alg_id);
1284 }
1285 switch (key->algorithm) {
1286 case SC_ALGORITHM_RSA:
1287 if (key->u.rsa.modulus.data)
1288 free(key->u.rsa.modulus.data);
1289 if (key->u.rsa.exponent.data)
1290 free(key->u.rsa.exponent.data);
1291 break;
1292 case SC_ALGORITHM_DSA:
1293 if (key->u.dsa.pub.data)
1294 free(key->u.dsa.pub.data);
1295 if (key->u.dsa.g.data)
1296 free(key->u.dsa.g.data);
1297 if (key->u.dsa.p.data)
1298 free(key->u.dsa.p.data);
1299 if (key->u.dsa.q.data)
1300 free(key->u.dsa.q.data);
1301 break;
1302 case SC_ALGORITHM_GOSTR3410:
1303 if (key->u.gostr3410.xy.data)
1304 free(key->u.gostr3410.xy.data);
1305 break;
1306 case SC_ALGORITHM_EC:
1307 if (key->u.ec.params.der.value)
1308 free(key->u.ec.params.der.value);
1309 if (key->u.ec.params.named_curve)
1310 free(key->u.ec.params.named_curve);
1311 if (key->u.ec.ecpointQ.value)
1312 free(key->u.ec.ecpointQ.value);
1313 break;
1314 case SC_ALGORITHM_EDDSA:
1315 case SC_ALGORITHM_XEDDSA:
1316 free(key->u.eddsa.pubkey.value);
1317 key->u.eddsa.pubkey.value = NULL;
1318 key->u.eddsa.pubkey.len = 0;
1319 break;
1320 }
1321 sc_mem_clear(key, sizeof(*key));
1322 }
1323
1324
1325 void
sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey * key)1326 sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *key)
1327 {
1328 if (!key)
1329 return;
1330 sc_pkcs15_erase_pubkey(key);
1331 free(key);
1332 }
1333
1334
1335 void
sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t * info)1336 sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *info)
1337 {
1338 if (info) {
1339 free(info->subject.value);
1340 free(info->direct.spki.value);
1341 free(info->direct.raw.value);
1342 sc_pkcs15_free_key_params(&info->params);
1343 free(info);
1344 }
1345 }
1346
1347
1348 static int
sc_pkcs15_read_der_file(sc_context_t * ctx,char * filename,u8 ** buf,size_t * buflen)1349 sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename,
1350 u8 ** buf, size_t * buflen)
1351 {
1352 int r;
1353 int f = -1;
1354 size_t len, offs;
1355 u8 tagbuf[16]; /* enough to read in the tag and length */
1356 u8 * rbuf = NULL;
1357 size_t rbuflen = 0;
1358 const u8 * body = NULL;
1359 size_t bodylen;
1360 unsigned int cla_out, tag_out;
1361
1362 LOG_FUNC_CALLED(ctx);
1363 if (!buf || !buflen)
1364 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1365
1366 *buf = NULL;
1367 *buflen = 0;
1368
1369 f = open(filename, O_RDONLY);
1370 if (f < 0) {
1371 r = SC_ERROR_FILE_NOT_FOUND;
1372 goto out;
1373 }
1374
1375 r = read(f, tagbuf, sizeof(tagbuf)); /* get tag and length */
1376 if (r < 2) {
1377 sc_log(ctx, "Problem with '%s'", filename);
1378 r = SC_ERROR_DATA_OBJECT_NOT_FOUND;
1379 goto out;
1380 }
1381 len = r;
1382
1383 body = tagbuf;
1384 r = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen);
1385 if (r != SC_SUCCESS && r != SC_ERROR_ASN1_END_OF_CONTENTS)
1386 goto out;
1387
1388 if (body == NULL) {
1389 r = SC_SUCCESS;
1390 goto out;
1391 }
1392
1393 offs = body - tagbuf;
1394 if (offs > len || offs < 2 || offs > offs + bodylen) {
1395 r = SC_ERROR_INVALID_ASN1_OBJECT;
1396 goto out;
1397 }
1398
1399 rbuflen = offs + bodylen;
1400 rbuf = malloc(rbuflen);
1401 if (rbuf == NULL) {
1402 r = SC_ERROR_OUT_OF_MEMORY;
1403 goto out;
1404 }
1405 memcpy(rbuf, tagbuf, len); /* copy first or only part */
1406 if (rbuflen > len) {
1407 /* read rest of file */
1408 r = read(f, rbuf + len, rbuflen - len);
1409 if (r < (int)(rbuflen - len)) {
1410 r = SC_ERROR_INVALID_ASN1_OBJECT;
1411 free (rbuf);
1412 rbuf = NULL;
1413 goto out;
1414 }
1415 }
1416 *buflen = rbuflen;
1417 *buf = rbuf;
1418 rbuf = NULL;
1419 r = rbuflen;
1420 out:
1421 if (f >= 0)
1422 close(f);
1423
1424 LOG_FUNC_RETURN(ctx, r);
1425 }
1426
1427 /*
1428 * can be used as an SC_ASN1_CALLBACK while parsing a certificate,
1429 * or can be called from the sc_pkcs15_pubkey_from_spki_file
1430 */
1431 int
sc_pkcs15_pubkey_from_spki_fields(struct sc_context * ctx,struct sc_pkcs15_pubkey ** outpubkey,unsigned char * buf,size_t buflen,int depth)1432 sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubkey **outpubkey,
1433 unsigned char *buf, size_t buflen, int depth)
1434 {
1435
1436 struct sc_pkcs15_pubkey *pubkey = NULL;
1437 struct sc_pkcs15_der pk = { NULL, 0 };
1438 struct sc_algorithm_id pk_alg;
1439 struct sc_asn1_entry asn1_pkinfo[C_ASN1_PKINFO_ATTR_SIZE];
1440 unsigned char *tmp_buf = NULL;
1441 int r;
1442
1443 sc_log(ctx,
1444 "sc_pkcs15_pubkey_from_spki_fields() called: %p:%"SC_FORMAT_LEN_SIZE_T"u\n%s",
1445 buf, buflen, sc_dump_hex(buf, buflen));
1446
1447 tmp_buf = malloc(buflen);
1448 if (!tmp_buf) {
1449 r = SC_ERROR_OUT_OF_MEMORY;
1450 LOG_TEST_GOTO_ERR(ctx, r, "");
1451 }
1452 memcpy(tmp_buf, buf, buflen);
1453
1454 if ((*tmp_buf & SC_ASN1_TAG_CONTEXT))
1455 *tmp_buf = SC_ASN1_TAG_CONSTRUCTED | SC_ASN1_TAG_SEQUENCE;
1456
1457 memset(&pk_alg, 0, sizeof(pk_alg));
1458 pubkey = calloc(1, sizeof(sc_pkcs15_pubkey_t));
1459 if (pubkey == NULL) {
1460 r = SC_ERROR_OUT_OF_MEMORY;
1461 LOG_TEST_GOTO_ERR(ctx, r, "");
1462 }
1463
1464 sc_copy_asn1_entry(c_asn1_pkinfo, asn1_pkinfo);
1465
1466 sc_format_asn1_entry(asn1_pkinfo + 0, &pk_alg, NULL, 0);
1467 sc_format_asn1_entry(asn1_pkinfo + 1, &pk.value, &pk.len, 0);
1468
1469 r = sc_asn1_decode(ctx, asn1_pkinfo, tmp_buf, buflen, NULL, NULL);
1470 if (r != SC_SUCCESS) {
1471 sc_asn1_clear_algorithm_id(&pk_alg);
1472 LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 parsing of subjectPubkeyInfo failed");
1473 }
1474
1475 pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id));
1476 if (pubkey->alg_id == NULL) {
1477 r = SC_ERROR_OUT_OF_MEMORY;
1478 LOG_TEST_GOTO_ERR(ctx, r, "");
1479 }
1480
1481 memcpy(pubkey->alg_id, &pk_alg, sizeof(struct sc_algorithm_id));
1482 pubkey->algorithm = pk_alg.algorithm;
1483 pk_alg.params = NULL;
1484 sc_log(ctx, "DEE pk_alg.algorithm=%d", pk_alg.algorithm);
1485
1486 pk.len = (pk.len + 7)/8; /* convert number of bits to bytes */
1487
1488 if (pk_alg.algorithm == SC_ALGORITHM_EC) {
1489 /* EC public key is not encapsulated into BIT STRING -- it's a BIT STRING */
1490 /*
1491 * sc_pkcs15_fix_ec_parameters below will set field_length from curve.
1492 * if no alg_id->params, assume field_length is multiple of 8
1493 */
1494 pubkey->u.ec.params.field_length = (pk.len - 1) / 2 * 8;
1495
1496 if (pubkey->alg_id->params) {
1497 struct sc_ec_parameters *ecp = (struct sc_ec_parameters *)pubkey->alg_id->params;
1498
1499 pubkey->u.ec.params.der.value = malloc(ecp->der.len);
1500 if (pubkey->u.ec.params.der.value == NULL) {
1501 r = SC_ERROR_OUT_OF_MEMORY;
1502 LOG_TEST_GOTO_ERR(ctx, r, "");
1503 }
1504
1505 memcpy(pubkey->u.ec.params.der.value, ecp->der.value, ecp->der.len);
1506 pubkey->u.ec.params.der.len = ecp->der.len;
1507 r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
1508 LOG_TEST_GOTO_ERR(ctx, r, "failed to fix EC parameters");
1509 }
1510
1511 pubkey->u.ec.ecpointQ.value = malloc(pk.len);
1512 if (pubkey->u.ec.ecpointQ.value == NULL) {
1513 r = SC_ERROR_OUT_OF_MEMORY;
1514 LOG_TEST_GOTO_ERR(ctx, r, "failed to malloc() memory");
1515 }
1516 memcpy(pubkey->u.ec.ecpointQ.value, pk.value, pk.len);
1517 pubkey->u.ec.ecpointQ.len = pk.len;
1518 } else if (pk_alg.algorithm == SC_ALGORITHM_EDDSA ||
1519 pk_alg.algorithm == SC_ALGORITHM_XEDDSA) {
1520 /* EDDSA/XEDDSA public key is not encapsulated into BIT STRING -- it's a BIT STRING */
1521 pubkey->u.eddsa.pubkey.value = malloc(pk.len);
1522 memcpy(pubkey->u.eddsa.pubkey.value, pk.value, pk.len);
1523 pubkey->u.eddsa.pubkey.len = pk.len;
1524 } else {
1525 /* Public key is expected to be encapsulated into BIT STRING */
1526 r = sc_pkcs15_decode_pubkey(ctx, pubkey, pk.value, pk.len);
1527 LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 parsing of subjectPubkeyInfo failed");
1528 }
1529
1530 *outpubkey = pubkey;
1531 pubkey = NULL;
1532
1533 err:
1534 if (pubkey)
1535 sc_pkcs15_free_pubkey(pubkey);
1536 if (pk.value)
1537 free(pk.value);
1538 if (tmp_buf)
1539 free(tmp_buf);
1540
1541 LOG_FUNC_RETURN(ctx, r);
1542 }
1543
1544
1545 int
sc_pkcs15_pubkey_from_spki_sequence(struct sc_context * ctx,const unsigned char * buf,size_t buflen,struct sc_pkcs15_pubkey ** outpubkey)1546 sc_pkcs15_pubkey_from_spki_sequence(struct sc_context *ctx, const unsigned char *buf, size_t buflen,
1547 struct sc_pkcs15_pubkey ** outpubkey)
1548 {
1549 struct sc_pkcs15_pubkey * pubkey = NULL;
1550 struct sc_asn1_entry asn1_spki[] = {
1551 { "subjectPublicKeyInfo", SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki_fields, &pubkey},
1552 { NULL, 0, 0, 0, NULL, NULL } };
1553 int r;
1554
1555 LOG_FUNC_CALLED(ctx);
1556
1557 r = sc_asn1_decode(ctx, asn1_spki, buf, buflen, NULL, NULL);
1558 LOG_TEST_RET(ctx, r, "ASN.1 cannot parse subjectPublicKeyInfo");
1559
1560 if(outpubkey) {
1561 free(*outpubkey);
1562 *outpubkey = pubkey;
1563 } else
1564 free(pubkey);
1565
1566 LOG_FUNC_RETURN(ctx, r);
1567 }
1568
1569
1570 int
sc_pkcs15_pubkey_from_spki_file(struct sc_context * ctx,char * filename,struct sc_pkcs15_pubkey ** outpubkey)1571 sc_pkcs15_pubkey_from_spki_file(struct sc_context *ctx, char * filename,
1572 struct sc_pkcs15_pubkey ** outpubkey)
1573 {
1574 int r;
1575 u8 * buf = NULL;
1576 size_t buflen = 0;
1577
1578 LOG_FUNC_CALLED(ctx);
1579
1580 r = sc_pkcs15_read_der_file(ctx, filename, &buf, &buflen);
1581 LOG_TEST_RET(ctx, r, "Cannot read SPKI DER file");
1582
1583 r = sc_pkcs15_pubkey_from_spki_sequence(ctx, buf, buflen, outpubkey);
1584 if (buf)
1585 free(buf);
1586
1587 LOG_FUNC_RETURN(ctx, r);
1588 }
1589
1590
1591 static struct ec_curve_info {
1592 const char *name;
1593 const char *oid_str;
1594 const char *oid_encoded;
1595 size_t size;
1596 } ec_curve_infos[] = {
1597 {"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
1598 {"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
1599 {"nistp192", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
1600 {"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
1601
1602 {"secp224r1", "1.3.132.0.33", "06052b81040021", 224},
1603 {"nistp224", "1.3.132.0.33", "06052b81040021", 224},
1604
1605 {"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
1606 {"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
1607 {"nistp256", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
1608 {"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
1609
1610 {"secp384r1", "1.3.132.0.34", "06052B81040022", 384},
1611 {"prime384v1", "1.3.132.0.34", "06052B81040022", 384},
1612 {"nistp384", "1.3.132.0.34", "06052B81040022", 384},
1613 {"ansiX9p384r1", "1.3.132.0.34", "06052B81040022", 384},
1614
1615 {"secp521r1", "1.3.132.0.35", "06052B81040023", 521},
1616 {"nistp521", "1.3.132.0.35", "06052B81040023", 521},
1617
1618 {"brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", "06092B2403030208010103", 192},
1619 {"brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", "06092B2403030208010105", 224},
1620 {"brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", "06092B2403030208010107", 256},
1621 {"brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", "06092B2403030208010109", 320},
1622 {"brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", "06092B240303020801010B", 384},
1623 {"brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", "06092B240303020801010D", 512},
1624
1625 {"secp192k1", "1.3.132.0.31", "06052B8104001F", 192},
1626 {"secp256k1", "1.3.132.0.10", "06052B8104000A", 256},
1627
1628 {"ed25519", "1.3.6.1.4.1.11591.15.1", "06092B06010401DA470F01", 255},
1629 {"curve25519", "1.3.6.1.4.1.3029.1.5.1", "060A2B060104019755010501", 255},
1630
1631 {NULL, NULL, NULL, 0}, /* Do not touch this */
1632 };
1633
1634
1635 int
sc_pkcs15_fix_ec_parameters(struct sc_context * ctx,struct sc_ec_parameters * ecparams)1636 sc_pkcs15_fix_ec_parameters(struct sc_context *ctx, struct sc_ec_parameters *ecparams)
1637 {
1638 int rv, ii;
1639
1640 LOG_FUNC_CALLED(ctx);
1641
1642 /* In PKCS#11 EC parameters arrives in DER encoded form */
1643 if (ecparams->der.value && ecparams->der.len) {
1644 for (ii=0; ec_curve_infos[ii].name; ii++) {
1645 struct sc_object_id id;
1646 unsigned char *buf = NULL;
1647 size_t len = 0;
1648
1649 sc_format_oid(&id, ec_curve_infos[ii].oid_str);
1650 sc_encode_oid (ctx, &id, &buf, &len);
1651
1652 if (ecparams->der.len == len && !memcmp(ecparams->der.value, buf, len)) {
1653 free(buf);
1654 break;
1655 }
1656
1657 free(buf);
1658 }
1659
1660 /* TODO: support of explicit EC parameters form */
1661 if (!ec_curve_infos[ii].name)
1662 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported named curve");
1663
1664 sc_log(ctx, "Found known curve '%s'", ec_curve_infos[ii].name);
1665 if (!ecparams->named_curve) {
1666 ecparams->named_curve = strdup(ec_curve_infos[ii].name);
1667 if (!ecparams->named_curve)
1668 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1669
1670 sc_log(ctx, "Curve name: '%s'", ecparams->named_curve);
1671 }
1672
1673 if (!sc_valid_oid(&ecparams->id))
1674 sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str);
1675
1676 ecparams->field_length = ec_curve_infos[ii].size;
1677 sc_log(ctx, "Curve length %"SC_FORMAT_LEN_SIZE_T"u",
1678 ecparams->field_length);
1679 }
1680 else if (ecparams->named_curve) { /* it can be name of curve or OID in ASCII form */
1681 for (ii=0; ec_curve_infos[ii].name; ii++) {
1682 if (!strcmp(ec_curve_infos[ii].name, ecparams->named_curve))
1683 break;
1684 if (!strcmp(ec_curve_infos[ii].oid_str, ecparams->named_curve))
1685 break;
1686 }
1687 if (!ec_curve_infos[ii].name) {
1688 sc_log(ctx, "Named curve '%s' not supported", ecparams->named_curve);
1689 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
1690 }
1691
1692 rv = sc_format_oid(&ecparams->id, ec_curve_infos[ii].oid_str);
1693 LOG_TEST_RET(ctx, rv, "Invalid OID format");
1694
1695 ecparams->field_length = ec_curve_infos[ii].size;
1696
1697 if (!ecparams->der.value || !ecparams->der.len) {
1698 rv = sc_encode_oid (ctx, &ecparams->id, &ecparams->der.value, &ecparams->der.len);
1699 LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
1700 }
1701 }
1702 else
1703 LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "EC parameters has to be presented as a named curve or explicit data");
1704
1705 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1706 }
1707
1708
1709 int
sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey * pkcs15_key,void * evp_key)1710 sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key)
1711 {
1712 #ifdef ENABLE_OPENSSL
1713 EVP_PKEY *pk = (EVP_PKEY *)evp_key;
1714 int pk_type;
1715 pk_type = EVP_PKEY_base_id(pk);
1716
1717 switch (pk_type) {
1718 case EVP_PKEY_RSA: {
1719 struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa;
1720 RSA *src = EVP_PKEY_get1_RSA(pk);
1721 const BIGNUM *src_n, *src_e;
1722
1723 RSA_get0_key(src, &src_n, &src_e, NULL);
1724
1725 pkcs15_key->algorithm = SC_ALGORITHM_RSA;
1726 if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) || !sc_pkcs15_convert_bignum(&dst->exponent, src_e))
1727 return SC_ERROR_INVALID_DATA;
1728 RSA_free(src);
1729 break;
1730 }
1731 case EVP_PKEY_DSA: {
1732 struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa;
1733 DSA *src = EVP_PKEY_get1_DSA(pk);
1734 const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g;
1735
1736 DSA_get0_key(src, &src_pub_key, &src_priv_key);
1737 DSA_get0_pqg(src, &src_p, &src_q, &src_g);
1738
1739 pkcs15_key->algorithm = SC_ALGORITHM_DSA;
1740 sc_pkcs15_convert_bignum(&dst->pub, src_pub_key);
1741 sc_pkcs15_convert_bignum(&dst->p, src_p);
1742 sc_pkcs15_convert_bignum(&dst->q, src_q);
1743 sc_pkcs15_convert_bignum(&dst->g, src_g);
1744 DSA_free(src);
1745 break;
1746 }
1747 #if !defined(OPENSSL_NO_EC)
1748 case NID_id_GostR3410_2001: {
1749 struct sc_pkcs15_pubkey_gostr3410 *dst = &pkcs15_key->u.gostr3410;
1750 EC_KEY *eckey = EVP_PKEY_get0(pk);
1751 const EC_POINT *point;
1752 BIGNUM *X, *Y;
1753 int r = 0;
1754
1755 assert(eckey);
1756 point = EC_KEY_get0_public_key(eckey);
1757 if (!point)
1758 return SC_ERROR_INTERNAL;
1759 X = BN_new();
1760 Y = BN_new();
1761 if (X && Y && EC_KEY_get0_group(eckey))
1762 r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey),
1763 point, X, Y, NULL);
1764 if (r == 1) {
1765 dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y);
1766 dst->xy.data = malloc(dst->xy.len);
1767 if (dst->xy.data) {
1768 BN_bn2bin(Y, dst->xy.data);
1769 BN_bn2bin(X, dst->xy.data + BN_num_bytes(Y));
1770 r = sc_mem_reverse(dst->xy.data, dst->xy.len);
1771 if (!r)
1772 r = 1;
1773 pkcs15_key->algorithm = SC_ALGORITHM_GOSTR3410;
1774 }
1775 else
1776 r = -1;
1777 }
1778 BN_free(X);
1779 BN_free(Y);
1780 if (r != 1)
1781 return SC_ERROR_INTERNAL;
1782 break;
1783 }
1784 case EVP_PKEY_EC: {
1785 struct sc_pkcs15_pubkey_ec *dst = &pkcs15_key->u.ec;
1786 const EC_KEY *src = NULL;
1787 const EC_GROUP *grp = NULL;
1788 unsigned char buf[255];
1789 size_t buflen = 255;
1790 int nid;
1791
1792 src = EVP_PKEY_get0_EC_KEY(pk);
1793 assert(src);
1794 assert(EC_KEY_get0_public_key(src));
1795
1796 pkcs15_key->algorithm = SC_ALGORITHM_EC;
1797 grp = EC_KEY_get0_group(src);
1798 if(grp == 0)
1799 return SC_ERROR_INCOMPATIBLE_KEY;
1800
1801 /* Decode EC_POINT from a octet string */
1802 buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src),
1803 POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL);
1804
1805 /* get curve name */
1806 nid = EC_GROUP_get_curve_name(grp);
1807 if(nid != 0) {
1808 const char *name = OBJ_nid2sn(nid);
1809 if (name)
1810 dst->params.named_curve = strdup(name);
1811 }
1812
1813 /* copy the public key */
1814 if (buflen > 0) {
1815 dst->ecpointQ.value = malloc(buflen);
1816 if (!dst->ecpointQ.value)
1817 return SC_ERROR_OUT_OF_MEMORY;
1818 memcpy(dst->ecpointQ.value, buf, buflen);
1819 dst->ecpointQ.len = buflen;
1820 /* calculate the field length */
1821 dst->params.field_length = (buflen - 1) / 2 * 8;
1822 }
1823 else
1824 return SC_ERROR_INCOMPATIBLE_KEY;
1825
1826 break;
1827 }
1828 #endif /* !defined(OPENSSL_NO_EC) */
1829 #ifdef EVP_PKEY_ED25519
1830 case EVP_PKEY_ED25519: {
1831 /* TODO */
1832 break;
1833 }
1834 #endif /* EVP_PKEY_ED25519 */
1835 default:
1836 return SC_ERROR_NOT_SUPPORTED;
1837 }
1838
1839 return SC_SUCCESS;
1840 #else
1841 return SC_ERROR_NOT_IMPLEMENTED;
1842 #endif
1843 }
1844