Coverage Report

Created: 2025-08-29 06:26

/src/opensc/src/libopensc/pkcs15-prkey.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkcs15-prkey.c: PKCS #15 private key functions
3
 *
4
 * Copyright (C) 2001, 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 <stdlib.h>
26
#include <string.h>
27
#include <stdio.h>
28
#include <assert.h>
29
30
#ifdef ENABLE_OPENSSL
31
#include <openssl/opensslv.h>
32
#include <openssl/bn.h>
33
#include <openssl/x509.h>
34
#include <openssl/x509v3.h>
35
#include <openssl/err.h>
36
#include <openssl/evp.h>
37
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
38
# include <openssl/core_names.h>
39
# include <openssl/param_build.h>
40
#endif
41
#ifndef OPENSSL_NO_EC
42
#include <openssl/ec.h>
43
#endif
44
#endif
45
46
#include "internal.h"
47
#include "asn1.h"
48
#include "pkcs15.h"
49
#include "common/compat_strlcpy.h"
50
#include "aux-data.h"
51
52
/*
53
 * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS  defined as 16
54
 */
55
#define C_ASN1_SUPPORTED_ALGORITHMS_SIZE (SC_MAX_SUPPORTED_ALGORITHMS + 1)
56
static const struct sc_asn1_entry c_asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE] = {
57
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
58
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
59
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
60
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
61
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
62
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
63
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
64
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
65
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
66
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
67
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
68
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
69
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
70
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
71
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
72
  { "algorithmReference", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
73
  { NULL, 0, 0, 0, NULL, NULL }
74
};
75
76
#define C_ASN1_COM_KEY_ATTR_SIZE 7
77
static const struct sc_asn1_entry c_asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE] = {
78
  { "iD",    SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
79
  { "usage",   SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
80
  { "native",  SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, SC_ASN1_OPTIONAL, NULL, NULL },
81
  { "accessFlags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
82
  { "keyReference",SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
83
/* Absent in PKCS#15-v1.1 but present in ISO 7816-15(2004-01-15)*/
84
  { "algReference", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
85
  { NULL, 0, 0, 0, NULL, NULL }
86
};
87
88
#define C_ASN1_COM_PRKEY_ATTR_SIZE 2
89
static const struct sc_asn1_entry c_asn1_com_prkey_attr[C_ASN1_COM_PRKEY_ATTR_SIZE] = {
90
  { "subjectName", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS,
91
    SC_ASN1_EMPTY_ALLOWED | SC_ASN1_ALLOC | SC_ASN1_OPTIONAL, NULL, NULL },
92
  { NULL, 0, 0, 0, NULL, NULL }
93
};
94
95
#define C_ASN1_RSAKEY_ATTR_SIZE 4
96
static const struct sc_asn1_entry c_asn1_rsakey_attr[] = {
97
  { "value",         SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
98
  { "modulusLength", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
99
  { "keyInfo",     SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
100
  { NULL, 0, 0, 0, NULL, NULL }
101
};
102
103
#define C_ASN1_PRK_RSA_ATTR_SIZE 2
104
static const struct sc_asn1_entry c_asn1_prk_rsa_attr[C_ASN1_PRK_RSA_ATTR_SIZE] = {
105
  { "privateRSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
106
  { NULL, 0, 0, 0, NULL, NULL }
107
};
108
109
#define C_ASN1_GOSTR3410KEY_ATTR_SIZE 5
110
static const struct sc_asn1_entry c_asn1_gostr3410key_attr[C_ASN1_GOSTR3410KEY_ATTR_SIZE] = {
111
  { "value",         SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
112
  { "params_r3410",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
113
  { "params_r3411",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
114
  { "params_28147",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
115
  { NULL, 0, 0, 0, NULL, NULL }
116
};
117
118
#define C_ASN1_PRK_GOSTR3410_ATTR_SIZE 2
119
static const struct sc_asn1_entry c_asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410_ATTR_SIZE] = {
120
  { "privateGOSTR3410KeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
121
  { NULL, 0, 0, 0, NULL, NULL }
122
};
123
124
/*
125
 * The element fieldSize is a proprietary extension to ISO 7816-15, providing to the middleware
126
 * the size of the underlying ECC field. This value is required for determine a proper size for
127
 * buffer allocations. The field follows the definition for modulusLength in RSA keys
128
 */
129
#define C_ASN1_ECCKEY_ATTR 5
130
static const struct sc_asn1_entry c_asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR] = {
131
  { "value",     SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
132
  { "fieldSize",     SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
133
  { "keyInfo",     SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
134
  /* Slovenian eID card also specifies ECC curve OID */
135
  { "ecDomain",      SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL},
136
  { NULL, 0, 0, 0, NULL, NULL }
137
};
138
139
#define C_ASN1_PRK_ECC_ATTR 2
140
static const struct sc_asn1_entry c_asn1_prk_ecc_attr[C_ASN1_PRK_ECC_ATTR] = {
141
  { "privateECCKeyAttributes", 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_PRKEY_SIZE 4
146
static const struct sc_asn1_entry c_asn1_prkey[C_ASN1_PRKEY_SIZE] = {
147
  { "privateRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
148
  { "privateECCKey", SC_ASN1_PKCS15_OBJECT,  0 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
149
  { "privateGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 4 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
150
  { NULL, 0, 0, 0, NULL, NULL }
151
};
152
153
154
int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card,
155
         struct sc_pkcs15_object *obj,
156
         const u8 ** buf, size_t *buflen)
157
5.01k
{
158
5.01k
  sc_context_t *ctx = p15card->card->ctx;
159
5.01k
  struct sc_pkcs15_prkey_info info;
160
5.01k
  int r, i, gostr3410_params[3];
161
5.01k
  struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
162
5.01k
  size_t usage_len = sizeof(info.usage);
163
5.01k
  size_t af_len = sizeof(info.access_flags);
164
5.01k
  struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
165
5.01k
  struct sc_asn1_entry asn1_com_prkey_attr[C_ASN1_COM_PRKEY_ATTR_SIZE];
166
5.01k
  struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE];
167
5.01k
  struct sc_asn1_entry asn1_prk_rsa_attr[C_ASN1_PRK_RSA_ATTR_SIZE];
168
5.01k
  struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOSTR3410KEY_ATTR_SIZE];
169
5.01k
  struct sc_asn1_entry asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410_ATTR_SIZE];
170
5.01k
  struct sc_asn1_entry asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR];
171
5.01k
  struct sc_asn1_entry asn1_prk_ecc_attr[C_ASN1_PRK_ECC_ATTR];
172
5.01k
  struct sc_asn1_entry asn1_prkey[C_ASN1_PRKEY_SIZE];
173
5.01k
  struct sc_asn1_entry asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE];
174
5.01k
  struct sc_asn1_pkcs15_object rsa_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr};
175
5.01k
  struct sc_asn1_pkcs15_object gostr3410_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_gostr3410_attr};
176
5.01k
  struct sc_asn1_pkcs15_object ecc_prkey_obj = { obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_ecc_attr };
177
5.01k
  u8 ec_domain[32];
178
5.01k
  size_t ec_domain_len = sizeof(ec_domain);
179
180
5.01k
  sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey);
181
5.01k
  sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
182
183
5.01k
  sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr);
184
5.01k
  sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
185
5.01k
  sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr);
186
5.01k
  sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
187
5.01k
  sc_copy_asn1_entry(c_asn1_prk_ecc_attr, asn1_prk_ecc_attr);
188
5.01k
  sc_copy_asn1_entry(c_asn1_ecckey_attr, asn1_ecckey_attr);
189
190
5.01k
  sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr);
191
5.01k
  sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
192
193
5.01k
  sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 0);
194
5.01k
  sc_format_asn1_entry(asn1_prkey + 1, &ecc_prkey_obj, NULL, 0);
195
5.01k
  sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 0);
196
197
5.01k
  sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 0);
198
5.01k
  sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 0);
199
5.01k
  sc_format_asn1_entry(asn1_prk_ecc_attr + 0, asn1_ecckey_attr, NULL, 0);
200
201
5.01k
  sc_format_asn1_entry(asn1_rsakey_attr + 0, &info.path, NULL, 0);
202
5.01k
  sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0);
203
204
5.01k
  sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0);
205
5.01k
  sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0);
206
5.01k
  sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0);
207
5.01k
  sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0);
208
209
5.01k
  sc_format_asn1_entry(asn1_ecckey_attr + 0, &info.path, NULL, 0);
210
5.01k
  sc_format_asn1_entry(asn1_ecckey_attr + 1, &info.field_length, NULL, 0);
211
5.01k
  sc_format_asn1_entry(asn1_ecckey_attr + 3, ec_domain, &ec_domain_len, 0);
212
213
5.01k
  sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0);
214
5.01k
  sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0);
215
5.01k
  sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0);
216
5.01k
  sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0);
217
5.01k
  sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0);
218
219
85.2k
  for (i=0; i<SC_MAX_SUPPORTED_ALGORITHMS && (asn1_supported_algorithms + i)->name; i++)
220
80.2k
    sc_format_asn1_entry(asn1_supported_algorithms + i, &info.algo_refs[i], NULL, 0);
221
5.01k
  sc_format_asn1_entry(asn1_com_key_attr + 5, asn1_supported_algorithms, NULL, 0);
222
223
5.01k
  sc_format_asn1_entry(asn1_com_prkey_attr + 0, &info.subject.value, &info.subject.len, 0);
224
225
  /* Fill in defaults */
226
5.01k
  memset(&info, 0, sizeof(info));
227
5.01k
  info.key_reference = -1;
228
5.01k
  info.native = 1;
229
5.01k
  memset(gostr3410_params, 0, sizeof(gostr3410_params));
230
231
5.01k
  r = sc_asn1_decode_choice(ctx, asn1_prkey, *buf, *buflen, buf, buflen);
232
5.01k
  if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
233
1.08k
    goto err;
234
3.92k
  LOG_TEST_GOTO_ERR(ctx, r, "PrKey DF ASN.1 decoding failed");
235
1.72k
  if (asn1_prkey[0].flags & SC_ASN1_PRESENT) {
236
457
    obj->type = SC_PKCS15_TYPE_PRKEY_RSA;
237
457
  }
238
1.26k
  else if (asn1_prkey[1].flags & SC_ASN1_PRESENT) {
239
97
    obj->type = SC_PKCS15_TYPE_PRKEY_EC;
240
97
#ifdef ENABLE_OPENSSL
241
97
    if (!(asn1_ecckey_attr[1].flags & SC_ASN1_PRESENT) && (asn1_ecckey_attr[3].flags & SC_ASN1_PRESENT)) {
242
8
      const unsigned char *p = ec_domain;
243
8
      ASN1_OBJECT *object = d2i_ASN1_OBJECT(NULL, &p, ec_domain_len);
244
8
      int nid;
245
8
      EC_GROUP *group;
246
8
      if (!object) {
247
3
        r = SC_ERROR_INVALID_ASN1_OBJECT;
248
3
        goto err;
249
3
      }
250
5
      nid = OBJ_obj2nid(object);
251
5
      ASN1_OBJECT_free(object);
252
5
      if (nid == NID_undef) {
253
1
        sc_log_openssl(ctx);
254
1
        r = SC_ERROR_OBJECT_NOT_FOUND;
255
1
        goto err;
256
1
      }
257
4
      group = EC_GROUP_new_by_curve_name(nid);
258
4
      if (!group) {
259
1
        sc_log_openssl(ctx);
260
1
        r = SC_ERROR_INVALID_DATA;
261
1
        goto err;
262
1
      }
263
3
      info.field_length = EC_GROUP_order_bits(group);
264
3
      EC_GROUP_free(group);
265
3
      if (!info.field_length) {
266
0
        sc_log_openssl(ctx);
267
0
        r = SC_ERROR_CORRUPTED_DATA;
268
0
        goto err;
269
0
      }
270
3
    }
271
97
#endif
272
97
  }
273
1.16k
  else if (asn1_prkey[2].flags & SC_ASN1_PRESENT) {
274
    /* FIXME proper handling of gost parameters without the need of
275
     * allocating data here. this would also make sc_pkcs15_free_key_params
276
     * obsolete */
277
30
    obj->type = SC_PKCS15_TYPE_PRKEY_GOSTR3410;
278
30
    if (info.modulus_length != 0 || info.params.len != 0) {
279
0
      r = SC_ERROR_INVALID_ASN1_OBJECT;
280
0
      goto err;
281
0
    }
282
30
    info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE;
283
30
    info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams);
284
30
    info.params.data = malloc(info.params.len);
285
30
    if (info.params.data == NULL) {
286
0
      r = SC_ERROR_OUT_OF_MEMORY;
287
0
      goto err;
288
0
    }
289
30
    keyinfo_gostparams = info.params.data;
290
30
    keyinfo_gostparams->gostr3410 = gostr3410_params[0];
291
30
    keyinfo_gostparams->gostr3411 = gostr3410_params[1];
292
30
    keyinfo_gostparams->gost28147 = gostr3410_params[2];
293
30
  }
294
1.13k
  else {
295
1.13k
    r = SC_ERROR_INVALID_ASN1_OBJECT;
296
1.13k
    LOG_TEST_GOTO_ERR(ctx, r, "Neither RSA or GOSTR3410 or ECC key in PrKDF entry.");
297
1.13k
  }
298
299
579
  if (!p15card->app || !p15card->app->ddo.aid.len) {
300
548
    if (!p15card->file_app) {
301
16
      r = SC_ERROR_INTERNAL;
302
16
      goto err;
303
16
    }
304
532
    r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
305
532
    if (r < 0) {
306
0
      goto err;
307
0
    }
308
532
  }
309
31
  else   {
310
31
    info.path.aid = p15card->app->ddo.aid;
311
31
  }
312
563
  sc_log(ctx, "PrivKey path '%s'", sc_print_path(&info.path));
313
314
  /* OpenSC 0.11.4 and older encoded "keyReference" as a negative value.
315
   * Fixed in 0.11.5 we need to add a hack, so old cards continue to work. */
316
563
  if (info.key_reference < -1)
317
104
    info.key_reference += 256;
318
319
  /* Check the auth_id - if not present, try and find it in access rules */
320
563
  if ((obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) && (obj->auth_id.len == 0)) {
321
265
    sc_log(ctx, "Private key %s has no auth ID - checking AccessControlRules",
322
265
        sc_pkcs15_print_id(&info.id));
323
324
    /* Search in the access_rules for an appropriate auth ID */
325
2.38k
    for (i = 0; i < SC_PKCS15_MAX_ACCESS_RULES; i++) {
326
      /* If access_mode is one of the private key usage modes */
327
2.12k
      if (obj->access_rules[i].access_mode &
328
2.12k
          (SC_PKCS15_ACCESS_RULE_MODE_EXECUTE |
329
2.12k
           SC_PKCS15_ACCESS_RULE_MODE_PSO_CDS |
330
2.12k
           SC_PKCS15_ACCESS_RULE_MODE_PSO_DECRYPT |
331
2.12k
           SC_PKCS15_ACCESS_RULE_MODE_INT_AUTH)) {
332
0
        if (obj->access_rules[i].auth_id.len != 0) {
333
          /* Found an auth ID to use for private key access */
334
0
          obj->auth_id = obj->access_rules[i].auth_id;
335
0
          sc_log(ctx, "Auth ID found - %s",
336
0
             sc_pkcs15_print_id(&obj->auth_id));
337
0
          break;
338
0
        }
339
0
      }
340
2.12k
    }
341
342
    /* No auth ID found */
343
265
    if (i == SC_PKCS15_MAX_ACCESS_RULES)
344
265
      sc_log(ctx, "Warning: No auth ID found");
345
265
  }
346
347
563
  obj->data = malloc(sizeof(info));
348
563
  if (obj->data == NULL) {
349
0
    r = SC_ERROR_OUT_OF_MEMORY;
350
0
    goto err;
351
0
  }
352
563
  memcpy(obj->data, &info, sizeof(info));
353
354
563
  sc_log(ctx, "Key Subject %s", sc_dump_hex(info.subject.value, info.subject.len));
355
563
  sc_log(ctx, "Key path %s", sc_print_path(&info.path));
356
357
563
  r = SC_SUCCESS;
358
359
5.01k
err:
360
5.01k
  if (r < 0) {
361
    /* This might have allocated something. If so, clear it now */
362
4.45k
    free(info.subject.value);
363
4.45k
    sc_pkcs15_free_key_params(&info.params);
364
4.45k
  }
365
366
5.01k
  return r;
367
563
}
368
369
int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj,
370
         u8 **buf, size_t *buflen)
371
1.75k
{
372
1.75k
  struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
373
1.75k
  struct sc_asn1_entry asn1_com_prkey_attr[C_ASN1_COM_PRKEY_ATTR_SIZE];
374
1.75k
  struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE];
375
1.75k
  struct sc_asn1_entry asn1_prk_rsa_attr[C_ASN1_PRK_RSA_ATTR_SIZE];
376
1.75k
  struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOSTR3410KEY_ATTR_SIZE];
377
1.75k
  struct sc_asn1_entry asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410_ATTR_SIZE];
378
1.75k
  struct sc_asn1_entry asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR];
379
1.75k
  struct sc_asn1_entry asn1_prk_ecc_attr[C_ASN1_PRK_ECC_ATTR];
380
1.75k
  struct sc_asn1_entry asn1_prkey[C_ASN1_PRKEY_SIZE];
381
1.75k
  struct sc_asn1_entry asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE];
382
1.75k
  struct sc_asn1_pkcs15_object rsa_prkey_obj = {
383
1.75k
    (struct sc_pkcs15_object *) obj, asn1_com_key_attr,
384
1.75k
    asn1_com_prkey_attr, asn1_prk_rsa_attr
385
1.75k
  };
386
1.75k
  struct sc_asn1_pkcs15_object gostr3410_prkey_obj = {
387
1.75k
    (struct sc_pkcs15_object *) obj,
388
1.75k
    asn1_com_key_attr, asn1_com_prkey_attr,
389
1.75k
    asn1_prk_gostr3410_attr
390
1.75k
  };
391
1.75k
  struct sc_asn1_pkcs15_object ecc_prkey_obj = {
392
1.75k
    (struct sc_pkcs15_object *) obj,
393
1.75k
    asn1_com_key_attr, asn1_com_prkey_attr,
394
1.75k
    asn1_prk_ecc_attr
395
1.75k
  };
396
1.75k
  struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data;
397
1.75k
  struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
398
1.75k
  int r, i;
399
1.75k
  size_t af_len, usage_len;
400
401
1.75k
  sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey);
402
1.75k
  sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
403
404
1.75k
  sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr);
405
1.75k
  sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
406
1.75k
  sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr);
407
1.75k
  sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
408
1.75k
  sc_copy_asn1_entry(c_asn1_prk_ecc_attr, asn1_prk_ecc_attr);
409
1.75k
  sc_copy_asn1_entry(c_asn1_ecckey_attr, asn1_ecckey_attr);
410
411
1.75k
  sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr);
412
1.75k
  sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
413
414
1.75k
  switch (obj->type) {
415
1.65k
  case SC_PKCS15_TYPE_PRKEY_RSA:
416
1.65k
    sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 1);
417
1.65k
    sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 1);
418
1.65k
    sc_format_asn1_entry(asn1_rsakey_attr + 0, &prkey->path, NULL, 1);
419
1.65k
    sc_format_asn1_entry(asn1_rsakey_attr + 1, &prkey->modulus_length, NULL, 1);
420
1.65k
    break;
421
96
  case SC_PKCS15_TYPE_PRKEY_EC:
422
96
    sc_format_asn1_entry(asn1_prkey + 1, &ecc_prkey_obj, NULL, 1);
423
96
    sc_format_asn1_entry(asn1_prk_ecc_attr + 0, asn1_ecckey_attr, NULL, 1);
424
96
    sc_format_asn1_entry(asn1_ecckey_attr + 0, &prkey->path, NULL, 1);
425
96
    sc_format_asn1_entry(asn1_ecckey_attr + 1, &prkey->field_length, NULL, 1);
426
96
    break;
427
0
  case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
428
0
    sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 1);
429
0
    sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 1);
430
0
    sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &prkey->path, NULL, 1);
431
0
    if (prkey->params.len == sizeof(*keyinfo_gostparams))   {
432
0
      keyinfo_gostparams = prkey->params.data;
433
0
      sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &keyinfo_gostparams->gostr3410, NULL, 1);
434
0
      sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &keyinfo_gostparams->gostr3411, NULL, 1);
435
0
      sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &keyinfo_gostparams->gost28147, NULL, 1);
436
0
    }
437
0
    break;
438
0
  default:
439
0
    sc_log(ctx, "Invalid private key type: %X", obj->type);
440
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
441
0
    break;
442
1.75k
  }
443
1.75k
  sc_format_asn1_entry(asn1_com_key_attr + 0, &prkey->id, NULL, 1);
444
1.75k
  usage_len = sizeof(prkey->usage);
445
1.75k
  sc_format_asn1_entry(asn1_com_key_attr + 1, &prkey->usage, &usage_len, 1);
446
1.75k
  if (prkey->native == 0)
447
0
    sc_format_asn1_entry(asn1_com_key_attr + 2, &prkey->native, NULL, 1);
448
1.75k
  if (prkey->access_flags) {
449
1.38k
    af_len = sizeof(prkey->access_flags);
450
1.38k
    sc_format_asn1_entry(asn1_com_key_attr + 3, &prkey->access_flags, &af_len, 1);
451
1.38k
  }
452
1.75k
  if (prkey->key_reference >= 0)
453
1.57k
    sc_format_asn1_entry(asn1_com_key_attr + 4, &prkey->key_reference, NULL, 1);
454
455
1.75k
  for (i=0; i<SC_MAX_SUPPORTED_ALGORITHMS && prkey->algo_refs[i]; i++)   {
456
0
    sc_log(ctx, "Encode algorithm(%i) %i", i, prkey->algo_refs[i]);
457
0
    sc_format_asn1_entry(asn1_supported_algorithms + i, &prkey->algo_refs[i], NULL, 1);
458
0
  }
459
1.75k
  sc_format_asn1_entry(asn1_com_key_attr + 5, asn1_supported_algorithms, NULL, prkey->algo_refs[0] != 0);
460
461
1.75k
  if (prkey->subject.value && prkey->subject.len)
462
0
    sc_format_asn1_entry(asn1_com_prkey_attr + 0, prkey->subject.value, &prkey->subject.len, 1);
463
1.75k
  else
464
1.75k
    memset(asn1_com_prkey_attr, 0, sizeof(asn1_com_prkey_attr));
465
466
1.75k
  r = sc_asn1_encode(ctx, asn1_prkey, buf, buflen);
467
468
1.75k
  sc_log(ctx, "Key path %s", sc_print_path(&prkey->path));
469
1.75k
  return r;
470
1.75k
}
471
472
int
473
sc_pkcs15_prkey_attrs_from_cert(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *cert_object,
474
    struct sc_pkcs15_object **out_key_object)
475
651
{
476
651
  struct sc_context *ctx = p15card->card->ctx;
477
651
#ifdef ENABLE_OPENSSL
478
651
  struct sc_pkcs15_object *key_object = NULL;
479
651
  struct sc_pkcs15_prkey_info *key_info = NULL;
480
651
  X509 *x = NULL;
481
651
  BIO *mem = NULL;
482
651
  unsigned char *buff = NULL, *ptr = NULL;
483
651
  int rv;
484
485
651
  LOG_FUNC_CALLED(ctx);
486
651
  if (out_key_object)
487
651
    *out_key_object = NULL;
488
489
651
  rv = sc_pkcs15_find_prkey_by_id(p15card, &((struct sc_pkcs15_cert_info *)cert_object->data)->id, &key_object);
490
651
  if (rv == SC_ERROR_OBJECT_NOT_FOUND)
491
651
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
492
296
  LOG_TEST_RET(ctx, rv, "Find private key error");
493
494
296
  key_info = (struct sc_pkcs15_prkey_info *) key_object->data;
495
496
296
  sc_log(ctx, "CertValue(%"SC_FORMAT_LEN_SIZE_T"u) %p",
497
296
         cert_object->content.len, cert_object->content.value);
498
296
  mem = BIO_new_mem_buf(cert_object->content.value, (int)cert_object->content.len);
499
296
  if (!mem) {
500
296
    sc_log_openssl(ctx);
501
296
    LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "MEM buffer allocation error");
502
296
  }
503
504
0
  x = d2i_X509_bio(mem, NULL);
505
0
  if (!x) {
506
0
    sc_log_openssl(ctx);
507
0
    LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "x509 parse error");
508
0
  }
509
0
  buff = OPENSSL_malloc(i2d_X509(x,NULL) + EVP_MAX_MD_SIZE);
510
0
  if (!buff) {
511
0
    sc_log_openssl(ctx);
512
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "OpenSSL allocation error");
513
0
  }
514
515
0
  ptr = buff;
516
0
  rv = i2d_X509_NAME(X509_get_subject_name(x), &ptr);
517
0
  if (rv <= 0) {
518
0
    sc_log_openssl(ctx);
519
0
    LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Get subject name error");
520
0
  }
521
522
0
  key_info->subject.value = malloc(rv);
523
0
  if (!key_info->subject.value)
524
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Subject allocation error");
525
526
0
  memcpy(key_info->subject.value, buff, rv);
527
0
  key_info->subject.len = rv;
528
529
0
  strlcpy(key_object->label, cert_object->label, sizeof(key_object->label));
530
531
0
  rv = 0;
532
533
0
  if (x)
534
0
    X509_free(x);
535
0
  if (mem)
536
0
    BIO_free(mem);
537
0
  if (buff)
538
0
    OPENSSL_free(buff);
539
540
0
  ERR_clear_error();
541
542
0
  if (out_key_object)
543
0
    *out_key_object = key_object;
544
545
0
  sc_log(ctx, "Subject %s", sc_dump_hex(key_info->subject.value, key_info->subject.len));
546
0
  LOG_FUNC_RETURN(ctx, rv);
547
#else
548
  LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
549
#endif
550
0
}
551
552
553
void
554
sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key)
555
9.52k
{
556
9.52k
  if (!key)
557
0
    return;
558
9.52k
  switch (key->algorithm) {
559
4.76k
  case SC_ALGORITHM_RSA:
560
4.76k
    free(key->u.rsa.modulus.data);
561
4.76k
    free(key->u.rsa.exponent.data);
562
4.76k
    free(key->u.rsa.d.data);
563
4.76k
    free(key->u.rsa.p.data);
564
4.76k
    free(key->u.rsa.q.data);
565
4.76k
    free(key->u.rsa.iqmp.data);
566
4.76k
    free(key->u.rsa.dmp1.data);
567
4.76k
    free(key->u.rsa.dmq1.data);
568
4.76k
    break;
569
0
  case SC_ALGORITHM_GOSTR3410:
570
0
    free(key->u.gostr3410.d.data);
571
0
    break;
572
4.76k
  case SC_ALGORITHM_EC:
573
4.76k
  case SC_ALGORITHM_EDDSA:
574
4.76k
  case SC_ALGORITHM_XEDDSA:
575
    /* EC, Edwards and Montgomery use common ec params */
576
4.76k
    sc_clear_ec_params(&key->u.ec.params);
577
4.76k
    free(key->u.ec.privateD.data);
578
4.76k
    free(key->u.ec.ecpointQ.value);
579
4.76k
    break;
580
9.52k
  }
581
9.52k
  sc_mem_clear(key, sizeof(*key));
582
9.52k
}
583
584
void
585
sc_pkcs15_free_prkey(struct sc_pkcs15_prkey *key)
586
7
{
587
7
  if (!key)
588
7
    return;
589
0
  sc_pkcs15_erase_prkey(key);
590
0
  free(key);
591
0
}
592
593
void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key)
594
18.1k
{
595
18.1k
  if (!key)
596
19
    return;
597
598
18.1k
  if (key->subject.value)
599
175
    free(key->subject.value);
600
601
18.1k
  sc_pkcs15_free_key_params(&key->params);
602
603
18.1k
  sc_aux_data_free(&key->aux_data);
604
605
18.1k
  free(key);
606
18.1k
}
607
608
int
609
sc_pkcs15_convert_bignum(sc_pkcs15_bignum_t *dst, const void *src)
610
0
{
611
0
#ifdef ENABLE_OPENSSL
612
0
  const BIGNUM *bn = (const BIGNUM *)src;
613
614
0
  if (bn == 0)
615
0
    return 0;
616
0
  dst->len = BN_num_bytes(bn);
617
0
  dst->data = malloc(dst->len);
618
0
  if (!dst->data)
619
0
    return 0;
620
0
  BN_bn2bin(bn, dst->data);
621
0
  return 1;
622
#else
623
  return 0;
624
#endif
625
0
}
626
627
int
628
sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key)
629
0
{
630
0
#ifdef ENABLE_OPENSSL
631
0
  EVP_PKEY *pk = (EVP_PKEY *)evp_key;
632
0
  int pk_type;
633
0
   pk_type = EVP_PKEY_base_id(pk);
634
635
0
  switch (pk_type) {
636
0
  case EVP_PKEY_RSA: {
637
0
    struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa;
638
639
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
640
0
    const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1;
641
0
    RSA *src = NULL;
642
0
    if (!(src = EVP_PKEY_get1_RSA(pk)))
643
0
      return SC_ERROR_INCOMPATIBLE_KEY;
644
645
0
    RSA_get0_key(src, &src_n, &src_e, &src_d);
646
0
    RSA_get0_factors(src, &src_p, &src_q);
647
0
    RSA_get0_crt_params(src, &src_dmp1, &src_dmq1, &src_iqmp);
648
#else
649
    BIGNUM *src_n = NULL, *src_e = NULL, *src_d = NULL, *src_p = NULL, *src_q = NULL;
650
    BIGNUM *src_iqmp = NULL, *src_dmp1 = NULL, *src_dmq1 = NULL;
651
    if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &src_n) != 1 ||
652
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_E, &src_e) != 1 ||
653
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_D, &src_d) != 1 ||
654
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_FACTOR1, &src_p) != 1 ||
655
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_FACTOR2, &src_q) != 1 ||
656
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_EXPONENT1, &src_dmp1) != 1 ||
657
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_EXPONENT2, &src_dmq1) != 1 ||
658
      EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &src_iqmp) != 1) {
659
      BN_free(src_n);
660
      BN_free(src_e);
661
      BN_free(src_d);
662
      BN_free(src_p);
663
      BN_free(src_q);
664
      BN_free(src_dmp1); BN_free(src_dmq1);
665
      return SC_ERROR_UNKNOWN;
666
    }
667
#endif
668
0
    pkcs15_key->algorithm = SC_ALGORITHM_RSA;
669
0
    if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) ||
670
0
      !sc_pkcs15_convert_bignum(&dst->exponent, src_e) ||
671
0
      !sc_pkcs15_convert_bignum(&dst->d, src_d) ||
672
0
      !sc_pkcs15_convert_bignum(&dst->p, src_p) ||
673
0
      !sc_pkcs15_convert_bignum(&dst->q, src_q)) {
674
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
675
      BN_free(src_n);
676
      BN_free(src_e);
677
      BN_free(src_d);
678
      BN_free(src_p);
679
      BN_free(src_q);
680
      BN_free(src_iqmp);
681
      BN_free(src_dmp1);
682
      BN_free(src_dmq1);
683
#else
684
0
      RSA_free(src);
685
0
#endif
686
0
      return SC_ERROR_NOT_SUPPORTED;
687
0
     }
688
0
    if (src_iqmp && src_dmp1 && src_dmq1) {
689
0
      sc_pkcs15_convert_bignum(&dst->iqmp, src_iqmp);
690
0
      sc_pkcs15_convert_bignum(&dst->dmp1, src_dmp1);
691
0
      sc_pkcs15_convert_bignum(&dst->dmq1, src_dmq1);
692
0
    }
693
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
694
0
    RSA_free(src);
695
#else
696
    BN_free(src_n);
697
    BN_free(src_e);
698
    BN_free(src_d);
699
    BN_free(src_p);
700
    BN_free(src_q);
701
    BN_free(src_iqmp);
702
    BN_free(src_dmp1);
703
    BN_free(src_dmq1);
704
#endif
705
0
    break;
706
0
    }
707
708
0
#if !defined(OPENSSL_NO_EC)
709
0
  case NID_id_GostR3410_2001: {
710
0
    struct sc_pkcs15_prkey_gostr3410 *dst = &pkcs15_key->u.gostr3410;
711
0
    pkcs15_key->algorithm = SC_ALGORITHM_GOSTR3410;
712
713
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
714
0
    const BIGNUM *src_priv_key = NULL;
715
0
    EC_KEY *src = NULL;
716
0
    if (!(src = EVP_PKEY_get0(pk)))
717
0
      return SC_ERROR_INCOMPATIBLE_KEY;
718
0
    if (!(src_priv_key = EC_KEY_get0_private_key(src)))
719
0
      return SC_ERROR_INTERNAL;
720
#else
721
    BIGNUM *src_priv_key = NULL;
722
    if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1) {
723
      return SC_ERROR_UNKNOWN;
724
    }
725
#endif
726
0
    sc_pkcs15_convert_bignum(&dst->d, src_priv_key);
727
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
728
0
    EC_KEY_free(src);
729
#else
730
    BN_free(src_priv_key);
731
#endif
732
0
    break;
733
0
    }
734
735
0
  case EVP_PKEY_EC: {
736
0
    struct sc_pkcs15_prkey_ec *dst = &pkcs15_key->u.ec;
737
0
    unsigned char buf[255];
738
0
    size_t buflen = 255;
739
0
    int nid;
740
0
    pkcs15_key->algorithm = SC_ALGORITHM_EC;
741
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
742
0
    const EC_KEY *src = NULL;
743
0
    const EC_GROUP *grp = NULL;
744
0
    const BIGNUM *src_priv_key = NULL;
745
0
    const EC_POINT *src_pub_key = NULL;
746
0
    if (!(src = EVP_PKEY_get0_EC_KEY(pk)))
747
0
      return SC_ERROR_INCOMPATIBLE_KEY;
748
0
    if (!(src_priv_key = EC_KEY_get0_private_key(src)) ||
749
0
      !(src_pub_key = EC_KEY_get0_public_key(src)) ||
750
0
      !(grp = EC_KEY_get0_group(src)))
751
0
      return SC_ERROR_INCOMPATIBLE_KEY;
752
0
    nid = EC_GROUP_get_curve_name(grp);
753
#else
754
    EC_GROUP *grp = NULL;
755
    BIGNUM *src_priv_key = NULL;
756
    char grp_name[256];
757
758
    if (EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY, &src_priv_key) != 1) {
759
      return SC_ERROR_UNKNOWN;
760
    }
761
762
    if (EVP_PKEY_get_group_name(pk, grp_name, sizeof(grp_name), NULL) != 1) {
763
      BN_free(src_priv_key);
764
      return SC_ERROR_UNKNOWN;
765
    }
766
    if ((nid = OBJ_sn2nid(grp_name)) == 0) {
767
      BN_free(src_priv_key);
768
      return SC_ERROR_UNKNOWN;
769
    }
770
    if ((grp = EC_GROUP_new_by_curve_name(nid)) == NULL) {
771
      BN_free(src_priv_key);
772
      return SC_ERROR_UNKNOWN;
773
    }
774
#endif
775
776
0
    if (!sc_pkcs15_convert_bignum(&dst->privateD, src_priv_key)) {
777
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
778
      BN_free(src_priv_key);
779
      EC_GROUP_free(grp);
780
#endif
781
0
      return SC_ERROR_INCOMPATIBLE_KEY;
782
0
    }
783
784
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
785
0
    if(nid != 0) {
786
0
      const char *sn = OBJ_nid2sn(nid);
787
0
      if (sn)
788
0
        dst->params.named_curve = strdup(sn);
789
0
    }
790
#else
791
    dst->params.named_curve = strdup(grp_name);
792
    BN_free(src_priv_key);
793
#endif
794
795
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
796
    /* Decode EC_POINT from a octet string */
797
0
    buflen = EC_POINT_point2oct(grp, src_pub_key,
798
0
        POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL);
799
0
    if (!buflen)
800
0
      return SC_ERROR_INCOMPATIBLE_KEY;
801
#else
802
    /* Decode EC_POINT from a octet string */
803
    if (EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, buf, buflen, &buflen) != 1) {
804
      return SC_ERROR_INCOMPATIBLE_KEY;
805
    }
806
#endif
807
    /* copy the public key */
808
0
    dst->ecpointQ.value = malloc(buflen);
809
0
    if (!dst->ecpointQ.value)
810
0
      return SC_ERROR_OUT_OF_MEMORY;
811
0
    memcpy(dst->ecpointQ.value, buf, buflen);
812
0
    dst->ecpointQ.len = buflen;
813
814
    /*
815
     * In OpenSC the field_length is in bits. Not all curves are a multiple of 8.
816
     * EC_POINT_point2oct handles this and returns octstrings that can handle
817
     * these curves. Get real field_length from OpenSSL.
818
     */
819
0
    dst->params.field_length = EC_GROUP_get_degree(grp);
820
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
821
    EC_GROUP_free(grp);
822
#endif
823
824
    /* Octetstring may need leading zeros if BN is to short */
825
0
    if (dst->privateD.len < BYTES4BITS(dst->params.field_length)) {
826
0
      size_t d = BYTES4BITS(dst->params.field_length) - dst->privateD.len;
827
828
0
      dst->privateD.data = realloc(dst->privateD.data, dst->privateD.len + d);
829
0
      if (!dst->privateD.data)
830
0
        return SC_ERROR_OUT_OF_MEMORY;
831
832
0
      memmove(dst->privateD.data + d, dst->privateD.data, dst->privateD.len);
833
0
      memset(dst->privateD.data, 0, d);
834
835
0
      dst->privateD.len += d;
836
0
    }
837
838
0
    break;
839
0
  }
840
0
#endif /* !defined(OPENSSL_NO_EC) */
841
0
#ifdef EVP_PKEY_ED25519
842
0
  case EVP_PKEY_ED25519: {
843
    /* TODO */
844
0
    break;
845
0
  }
846
0
#endif /* EVP_PKEY_ED25519 */
847
848
0
  default:
849
0
    return SC_ERROR_NOT_SUPPORTED;
850
0
  }
851
852
0
  return SC_SUCCESS;
853
#else
854
  return SC_ERROR_NOT_IMPLEMENTED;
855
#endif
856
0
}