Coverage Report

Created: 2025-07-12 06:53

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