Coverage Report

Created: 2025-08-26 06:43

/src/opensc/src/libopensc/pkcs15-algo.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkc15-algo.c: ASN.1 handling for algorithm IDs and parameters
3
 *
4
 * Copyright (C) 2001, 2002  Olaf Kirch <okir@suse.de>
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 <stdio.h>
26
#include <string.h>
27
#include <ctype.h>
28
#include <assert.h>
29
#include <stdlib.h>
30
31
#include "internal.h"
32
#include "asn1.h"
33
34
/*
35
 * AlgorithmIdentifier handling
36
 */
37
static struct sc_asn1_entry c_asn1_des_iv[] = {
38
  { "iv", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
39
  { NULL, 0, 0, 0, NULL, NULL }
40
};
41
42
static int
43
asn1_decode_des_params(sc_context_t *ctx, void **paramp,
44
        const u8 *buf, size_t buflen, int depth)
45
0
{
46
0
  struct sc_asn1_entry asn1_des_iv[2];
47
0
  u8  iv[8];
48
0
  size_t ivlen = 8;
49
0
  int r;
50
51
0
  sc_copy_asn1_entry(c_asn1_des_iv, asn1_des_iv);
52
0
  sc_format_asn1_entry(asn1_des_iv + 0, iv, &ivlen, 0);
53
0
  r = _sc_asn1_decode(ctx, asn1_des_iv, buf, buflen, NULL, NULL, 0, depth + 1);
54
0
  if (r < 0)
55
0
    return r;
56
0
  if (ivlen != 8)
57
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
58
0
  *paramp = malloc(8);
59
0
  if (!*paramp)
60
0
    return SC_ERROR_OUT_OF_MEMORY;
61
0
  memcpy(*paramp, iv, 8);
62
0
  return 0;
63
0
}
64
65
static int
66
asn1_encode_des_params(sc_context_t *ctx, void *params,
67
        u8 **buf, size_t *buflen, int depth)
68
0
{
69
0
  struct sc_asn1_entry asn1_des_iv[2];
70
0
  int ivlen = 8;
71
72
0
  sc_copy_asn1_entry(c_asn1_des_iv, asn1_des_iv);
73
0
  sc_format_asn1_entry(asn1_des_iv + 0, params, &ivlen, 1);
74
0
  return _sc_asn1_encode(ctx, asn1_des_iv, buf, buflen, depth + 1);
75
0
}
76
77
static const struct sc_asn1_entry c_asn1_gostr3410_params0[] = {
78
  { "GOSTR3410Params", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
79
  { NULL, 0, 0, 0, NULL, NULL }
80
};
81
82
static const struct sc_asn1_entry c_asn1_gostr3410_params[] = {
83
  { "key_params", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
84
  { "hash_params", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
85
  { "cipher_params", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
86
  { NULL, 0, 0, 0, NULL, NULL }
87
};
88
89
static int
90
asn1_decode_gostr3410_params(sc_context_t *ctx, void **paramp,
91
    const u8 *buf, size_t buflen, int depth)
92
0
{
93
0
  struct sc_asn1_entry asn1_gostr3410_params0[2], asn1_gostr3410_params[4];
94
0
  struct sc_object_id keyp, hashp, cipherp;
95
0
  int r;
96
97
0
  sc_copy_asn1_entry(c_asn1_gostr3410_params0, asn1_gostr3410_params0);
98
0
  sc_copy_asn1_entry(c_asn1_gostr3410_params, asn1_gostr3410_params);
99
100
0
  sc_format_asn1_entry(asn1_gostr3410_params0 + 0, asn1_gostr3410_params, NULL, 0);
101
0
  sc_format_asn1_entry(asn1_gostr3410_params + 0, &keyp, NULL, 0);
102
0
  sc_format_asn1_entry(asn1_gostr3410_params + 1, &hashp, NULL, 0);
103
0
  sc_format_asn1_entry(asn1_gostr3410_params + 2, &cipherp, NULL, 0);
104
105
0
  r = _sc_asn1_decode(ctx, asn1_gostr3410_params0, buf, buflen, NULL, NULL, 0, depth + 1);
106
  /* TODO: store in paramp */
107
0
  (void)paramp; /* no warning */
108
0
  return r;
109
0
}
110
111
static int
112
asn1_encode_gostr3410_params(sc_context_t *ctx, void *params,
113
    u8 **buf, size_t *buflen, int depth)
114
0
{
115
0
  struct sc_asn1_entry asn1_gostr3410_params0[2], asn1_gostr3410_params[4];
116
0
  struct sc_pkcs15_gost_parameters *gost_params = (struct sc_pkcs15_gost_parameters *)params;
117
0
  int r;
118
119
0
  sc_copy_asn1_entry(c_asn1_gostr3410_params0, asn1_gostr3410_params0);
120
0
  sc_copy_asn1_entry(c_asn1_gostr3410_params, asn1_gostr3410_params);
121
122
0
  sc_format_asn1_entry(asn1_gostr3410_params0 + 0, asn1_gostr3410_params, NULL, 1);
123
0
  sc_format_asn1_entry(asn1_gostr3410_params + 0, &gost_params->key, NULL, 1);
124
0
  sc_format_asn1_entry(asn1_gostr3410_params + 1, &gost_params->hash, NULL, 1);
125
  /* sc_format_asn1_entry(asn1_gostr3410_params + 2, &cipherp, NULL, 1); */
126
127
0
  r = _sc_asn1_encode(ctx, asn1_gostr3410_params0, buf, buflen, depth + 1);
128
129
0
  sc_log(ctx, "encoded-params: %s", sc_dump_hex(*buf, *buflen));
130
0
  return r;
131
0
}
132
133
static const struct sc_asn1_entry c_asn1_pbkdf2_params[] = {
134
  { "salt", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
135
  { "count",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
136
  { "keyLength",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
137
  { "prf",  SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
138
  { NULL, 0, 0, 0, NULL, NULL }
139
};
140
141
static int
142
asn1_decode_pbkdf2_params(sc_context_t *ctx, void **paramp,
143
        const u8 *buf, size_t buflen, int depth)
144
0
{
145
0
  struct sc_pbkdf2_params info;
146
0
  struct sc_asn1_entry asn1_pbkdf2_params[5];
147
0
  int r;
148
149
0
  sc_copy_asn1_entry(c_asn1_pbkdf2_params, asn1_pbkdf2_params);
150
0
  sc_format_asn1_entry(asn1_pbkdf2_params + 0,
151
0
      info.salt, &info.salt_len, 0);
152
0
  sc_format_asn1_entry(asn1_pbkdf2_params + 1,
153
0
      &info.iterations, NULL, 0);
154
0
  sc_format_asn1_entry(asn1_pbkdf2_params + 2,
155
0
      &info.key_length, NULL, 0);
156
0
  sc_format_asn1_entry(asn1_pbkdf2_params + 3,
157
0
      &info.hash_alg, NULL, 0);
158
159
0
  memset(&info, 0, sizeof(info));
160
0
  info.salt_len = sizeof(info.salt);
161
0
  info.hash_alg.algorithm = SC_ALGORITHM_SHA1;
162
163
0
  r = _sc_asn1_decode(ctx, asn1_pbkdf2_params, buf, buflen, NULL, NULL, 0, depth + 1);
164
0
  if (r < 0)
165
0
    return r;
166
167
0
  *paramp = malloc(sizeof(info));
168
0
  if (!*paramp)
169
0
    return SC_ERROR_OUT_OF_MEMORY;
170
0
  memcpy(*paramp, &info, sizeof(info));
171
0
  return 0;
172
0
}
173
174
static int
175
asn1_encode_pbkdf2_params(sc_context_t *ctx, void *params,
176
        u8 **buf, size_t *buflen, int depth)
177
0
{
178
0
  struct sc_pbkdf2_params *info;
179
0
  struct sc_asn1_entry asn1_pbkdf2_params[5];
180
181
0
  info = (struct sc_pbkdf2_params *) params;
182
183
0
  sc_copy_asn1_entry(c_asn1_pbkdf2_params, asn1_pbkdf2_params);
184
0
  sc_format_asn1_entry(asn1_pbkdf2_params + 0,
185
0
      info->salt, &info->salt_len, 1);
186
0
  sc_format_asn1_entry(asn1_pbkdf2_params + 1,
187
0
      &info->iterations, NULL, 1);
188
0
  if (info->key_length > 0)
189
0
    sc_format_asn1_entry(asn1_pbkdf2_params + 2,
190
0
        &info->key_length, NULL, 1);
191
0
  if (info->hash_alg.algorithm != SC_ALGORITHM_SHA1)
192
0
    sc_format_asn1_entry(asn1_pbkdf2_params + 3,
193
0
        &info->hash_alg, NULL, 0);
194
195
0
  return _sc_asn1_encode(ctx, asn1_pbkdf2_params, buf, buflen, depth + 1);
196
0
}
197
198
static const struct sc_asn1_entry c_asn1_pbes2_params[] = {
199
  { "keyDerivationAlg", SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
200
  { "keyEcnryptionAlg", SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
201
  { NULL, 0, 0, 0, NULL, NULL }
202
};
203
204
static int
205
asn1_decode_pbes2_params(sc_context_t *ctx, void **paramp,
206
        const u8 *buf, size_t buflen, int depth)
207
0
{
208
0
  struct sc_asn1_entry asn1_pbes2_params[3];
209
0
  struct sc_pbes2_params info;
210
0
  int r;
211
212
0
  sc_copy_asn1_entry(c_asn1_pbes2_params, asn1_pbes2_params);
213
0
  sc_format_asn1_entry(asn1_pbes2_params + 0,
214
0
        &info.derivation_alg, NULL, 0);
215
0
  sc_format_asn1_entry(asn1_pbes2_params + 1,
216
0
        &info.key_encr_alg, NULL, 0);
217
0
  memset(&info, 0, sizeof(info));
218
219
0
  r = _sc_asn1_decode(ctx, asn1_pbes2_params, buf, buflen, NULL, NULL, 0, depth + 1);
220
0
  if (r < 0)
221
0
    return r;
222
0
  *paramp = malloc(sizeof(info));
223
0
  if (!*paramp)
224
0
    return SC_ERROR_OUT_OF_MEMORY;
225
0
  memcpy(*paramp, &info, sizeof(info));
226
0
  return 0;
227
0
}
228
229
static int
230
asn1_encode_pbes2_params(sc_context_t *ctx, void *params,
231
        u8 **buf, size_t *buflen, int depth)
232
0
{
233
0
  struct sc_asn1_entry asn1_pbes2_params[3];
234
0
  struct sc_pbes2_params *info;
235
236
0
  info = (struct sc_pbes2_params *) params;
237
0
  sc_copy_asn1_entry(c_asn1_pbes2_params, asn1_pbes2_params);
238
0
  sc_format_asn1_entry(asn1_pbes2_params + 0,
239
0
        &info->derivation_alg, NULL, 0);
240
0
  sc_format_asn1_entry(asn1_pbes2_params + 1,
241
0
        &info->key_encr_alg, NULL, 0);
242
0
  return _sc_asn1_encode(ctx, asn1_pbes2_params, buf, buflen, depth + 1);
243
0
}
244
245
static void
246
asn1_free_pbes2_params(void *ptr)
247
0
{
248
0
  struct sc_pbes2_params *params = (struct sc_pbes2_params *) ptr;
249
250
0
  sc_asn1_clear_algorithm_id(&params->derivation_alg);
251
0
  sc_asn1_clear_algorithm_id(&params->key_encr_alg);
252
0
  free(params);
253
0
}
254
255
static const struct sc_asn1_entry c_asn1_ec_params[] = {
256
  { "ecParameters", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
257
  { "namedCurve", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL},
258
  { "implicityCA",  SC_ASN1_NULL, SC_ASN1_TAG_NULL, 0, NULL, NULL },
259
  { NULL, 0, 0, 0, NULL, NULL }
260
};
261
262
static int
263
asn1_decode_ec_params(sc_context_t *ctx, void **paramp,
264
  const u8 *buf, size_t buflen, int depth)
265
0
{
266
0
  int r;
267
0
  struct sc_object_id curve;
268
0
  struct sc_asn1_entry asn1_ec_params[4];
269
0
  struct sc_ec_parameters *ecp;
270
271
0
  memset(&curve, 0, sizeof(curve));
272
273
  /* We only want to copy the parms if they are a namedCurve
274
   * or ecParameters  nullParam aka implicityCA is not to be
275
   * used with PKCS#11 2.20 */
276
0
  sc_copy_asn1_entry(c_asn1_ec_params, asn1_ec_params);
277
0
  sc_format_asn1_entry(asn1_ec_params + 1, &curve, 0, 0);
278
279
  /* Some signature algorithms will not have any data */
280
0
  if (buflen == 0 || buf == NULL)
281
0
    return 0;
282
283
0
  r = sc_asn1_decode_choice(ctx, asn1_ec_params, buf, buflen, NULL, NULL);
284
  /* r = index in asn1_ec_params */
285
0
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "asn1_decode_ec_params r=%d", r);
286
0
  if (r < 0)
287
0
    return r;
288
289
0
  ecp = calloc(1, sizeof(struct sc_ec_parameters));
290
0
  if (ecp == NULL)
291
0
    return SC_ERROR_OUT_OF_MEMORY;
292
293
0
  if (r <= 1) {
294
0
    ecp->der.value = malloc(buflen);
295
0
    if (ecp->der.value == NULL) {
296
0
      free(ecp);
297
0
      return SC_ERROR_OUT_OF_MEMORY;
298
0
    }
299
0
    ecp->der.len = buflen;
300
0
    memcpy(ecp->der.value, buf, buflen);
301
0
  }
302
0
  else    {
303
0
    r = 0;
304
0
  }
305
306
0
  ecp->type = r; /* but 0 = ecparams if any, 1=named curve */
307
0
  *paramp = ecp;
308
0
  return SC_SUCCESS;
309
0
};
310
311
static int
312
asn1_encode_ec_params(sc_context_t *ctx, void *params,
313
u8 **buf, size_t *buflen, int depth)
314
0
{
315
0
   struct sc_ec_parameters *ecp = (struct sc_ec_parameters *) params;
316
317
  /* Only handle named curves. They may be absent too */
318
0
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "asn1_encode_ec_params() called");
319
0
  *buf = NULL;
320
0
  *buflen = 0;
321
0
  if (ecp && ecp->type == 1 && ecp->der.value) { /* named curve */
322
0
    *buf = malloc(ecp->der.len);
323
0
    if (*buf == NULL)
324
0
      return SC_ERROR_OUT_OF_MEMORY;
325
326
0
    memcpy(*buf, ecp->der.value, ecp->der.len);
327
0
    *buflen = ecp->der.len;
328
0
  }
329
0
  else   {
330
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Not named curve");
331
0
  }
332
333
0
  return 0;
334
0
}
335
336
static void
337
asn1_free_ec_params(void *params)
338
0
{
339
0
  struct sc_ec_parameters *ecp = (struct sc_ec_parameters *) params;
340
341
0
  if (ecp) {
342
0
    if (ecp->der.value)
343
0
      free(ecp->der.value);
344
0
    if (ecp->named_curve)
345
0
      free(ecp->named_curve);
346
0
    free(ecp);
347
0
  }
348
0
}
349
350
static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
351
#ifdef SC_ALGORITHM_SHA1
352
    /* hmacWithSHA1 */
353
    {SC_ALGORITHM_SHA1, {{1, 2, 840, 113549, 2, 7, -1}}, NULL, NULL, NULL},
354
    {SC_ALGORITHM_SHA1, {{1, 3, 6, 1, 5, 5, 8, 1, 2, -1}}, NULL, NULL, NULL},
355
    /* SHA1 */
356
    {SC_ALGORITHM_SHA1, {{1, 3, 14, 3, 2, 26, -1}}, NULL, NULL, NULL},
357
#endif
358
#ifdef SC_ALGORITHM_MD5
359
    {SC_ALGORITHM_MD5, {{1, 2, 840, 113549, 2, 5, -1}}, NULL, NULL, NULL},
360
#endif
361
#ifdef SC_ALGORITHM_RSA /* really rsaEncryption and id-RSASSA-PSS */
362
    {SC_ALGORITHM_RSA, {{1, 2, 840, 113549, 1, 1, 1, -1}}, NULL, NULL, NULL},
363
    {SC_ALGORITHM_RSA, {{1, 2, 840, 113549, 1, 1, 10, -1}}, NULL, NULL, NULL},
364
#endif
365
#ifdef SC_ALGORITHM_DH
366
    {SC_ALGORITHM_DH, {{1, 2, 840, 10046, 2, 1, -1}}, NULL, NULL, NULL},
367
#endif
368
#ifdef SC_ALGORITHM_RC2_WRAP /* from CMS */
369
    {SC_ALGORITHM_RC2_WRAP, {{1, 2, 840, 113549, 1, 9, 16, 3, 7, -1}}, NULL, NULL, NULL},
370
#endif
371
#ifdef SC_ALGORITHM_RC2 /* CBC mode */
372
    {SC_ALGORITHM_RC2, {{1, 2, 840, 113549, 3, 2, -1}},
373
      asn1_decode_rc2_params,
374
      asn1_encode_rc2_params},
375
#endif
376
#ifdef SC_ALGORITHM_DES /* CBC mode */
377
    {SC_ALGORITHM_DES, {{1, 3, 14, 3, 2, 7, -1}},
378
      asn1_decode_des_params,
379
      asn1_encode_des_params,
380
      free},
381
#endif
382
#ifdef SC_ALGORITHM_3DES_WRAP /* from CMS */
383
    {SC_ALGORITHM_3DES_WRAP, {{1, 2, 840, 113549, 1, 9, 16, 3, 6, -1}}, NULL, NULL, NULL},
384
#endif
385
#ifdef SC_ALGORITHM_3DES /* EDE CBC mode */
386
    {SC_ALGORITHM_3DES, {{1, 2, 840, 113549, 3, 7, -1}},
387
      asn1_decode_des_params,
388
      asn1_encode_des_params,
389
      free},
390
#endif
391
#ifdef SC_ALGORITHM_GOST /* EDE CBC mode */
392
    {SC_ALGORITHM_GOST, {{1, 2, 4434, 66565, 3, 7, -1}}, NULL, NULL, NULL},
393
#endif
394
#ifdef SC_ALGORITHM_GOSTR3410
395
    {SC_ALGORITHM_GOSTR3410, {{1, 2, 643, 2, 2, 19, -1}},
396
      asn1_decode_gostr3410_params,
397
      asn1_encode_gostr3410_params,
398
      NULL},
399
#endif
400
/* We do not support PBES1 because the encryption is weak */
401
#ifdef SC_ALGORITHM_PBKDF2
402
    {SC_ALGORITHM_PBKDF2, {{1, 2, 840, 113549, 1, 5, 12, -1}},
403
      asn1_decode_pbkdf2_params,
404
      asn1_encode_pbkdf2_params,
405
      free},
406
#endif
407
#ifdef SC_ALGORITHM_PBES2
408
    {SC_ALGORITHM_PBES2, {{1, 2, 840, 113549, 1, 5, 13, -1}},
409
      asn1_decode_pbes2_params,
410
      asn1_encode_pbes2_params,
411
      asn1_free_pbes2_params},
412
#endif
413
#ifdef SC_ALGORITHM_EC
414
    {SC_ALGORITHM_EC, {{1, 2, 840, 10045, 2, 1, -1}},
415
      asn1_decode_ec_params,
416
      asn1_encode_ec_params,
417
      asn1_free_ec_params},
418
#endif
419
#ifdef SC_ALGORITHM_ECDSA_SHA1
420
    /* Note RFC 3279 says no ecParameters */
421
    {SC_ALGORITHM_ECDSA_SHA1, {{1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL},
422
#endif
423
#ifdef SC_ALGORITHM_ECDSA_SHA224
424
    /* These next 4 are defined in RFC 5758 */
425
    {SC_ALGORITHM_ECDSA_SHA224, {{1, 2, 840, 10045, 4, 3, 1, -1}},
426
      asn1_decode_ec_params,
427
      asn1_encode_ec_params,
428
      asn1_free_ec_params},
429
#endif
430
#ifdef SC_ALGORITHM_ECDSA_SHA256
431
    {SC_ALGORITHM_ECDSA_SHA256, {{1, 2, 840, 10045, 4, 3, 2, -1}},
432
      asn1_decode_ec_params,
433
      asn1_encode_ec_params,
434
      asn1_free_ec_params},
435
#endif
436
#ifdef SC_ALGORITHM_ECDSA_SHA384
437
    {SC_ALGORITHM_ECDSA_SHA384, {{1, 2, 840, 10045, 4, 3, 3, -1}},
438
      asn1_decode_ec_params,
439
      asn1_encode_ec_params,
440
      asn1_free_ec_params},
441
#endif
442
#ifdef SC_ALGORITHM_ECDSA_SHA512
443
    {SC_ALGORITHM_ECDSA_SHA512, {{1, 2, 840, 10045, 4, 3, 4, -1}},
444
      asn1_decode_ec_params,
445
      asn1_encode_ec_params,
446
      asn1_free_ec_params},
447
#endif
448
#ifdef SC_ALGORITHM_EDDSA
449
    /* aka Ed25519 */
450
    /* RFC 8410, needed to parse/create X509 certs/pubkeys  */
451
    {SC_ALGORITHM_EDDSA, {{1, 3, 101, 112, -1}},
452
      asn1_decode_ec_params,
453
      asn1_encode_ec_params,
454
      asn1_free_ec_params}, /* Ed25119 */
455
    {SC_ALGORITHM_EDDSA, {{1, 3, 6, 1, 4, 1, 11591, 15, 1, -1}},
456
      asn1_decode_ec_params,
457
      asn1_encode_ec_params,
458
      asn1_free_ec_params}, /* Ed25519 OID used by OpenPGP */
459
    {SC_ALGORITHM_EDDSA, {{1, 3, 101, 113, -1}},
460
      asn1_decode_ec_params,
461
      asn1_encode_ec_params,
462
      asn1_free_ec_params}, /* Ed448 */
463
#endif
464
#ifdef SC_ALGORITHM_XEDDSA
465
    /* aka curve25519 */
466
    /* RFC 8410, needed to parse/create X509 certs/pubkeys  ec_parms*/
467
    {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 110, -1}},
468
      asn1_decode_ec_params,
469
      asn1_encode_ec_params,
470
      asn1_free_ec_params}, /* X25519 */
471
    {SC_ALGORITHM_XEDDSA, {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1 - 1}},
472
      asn1_decode_ec_params,
473
      asn1_encode_ec_params,
474
      asn1_free_ec_params}, /* X25519 OID used by OpenPGP */
475
    {SC_ALGORITHM_XEDDSA, {{1, 3, 101, 111, -1}},
476
      asn1_decode_ec_params,
477
      asn1_encode_ec_params,
478
      asn1_free_ec_params}, /* X448 */
479
#endif
480
    {-1, {{-1}}, NULL, NULL, NULL}
481
};
482
483
484
static struct sc_asn1_pkcs15_algorithm_info *
485
sc_asn1_get_algorithm_info(const struct sc_algorithm_id *id)
486
0
{
487
0
  struct sc_asn1_pkcs15_algorithm_info *aip = NULL;
488
489
0
  for (aip = algorithm_table; aip->id >= 0; aip++)   {
490
0
    if ((int) id->algorithm < 0 && sc_compare_oid(&id->oid, &aip->oid))
491
0
      return aip;
492
493
0
    if (aip->id == (int)id->algorithm)
494
0
      return aip;
495
0
  }
496
497
0
  return NULL;
498
0
}
499
500
static const struct sc_asn1_entry c_asn1_alg_id[3] = {
501
  { "algorithm",  SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
502
  { "nullParam",  SC_ASN1_NULL, SC_ASN1_TAG_NULL, SC_ASN1_OPTIONAL, NULL, NULL },
503
  { NULL, 0, 0, 0, NULL, NULL }
504
};
505
506
int
507
sc_asn1_decode_algorithm_id(struct sc_context *ctx, const unsigned char *in,
508
          size_t len, struct sc_algorithm_id *id,
509
          int depth)
510
0
{
511
0
  struct sc_asn1_pkcs15_algorithm_info *alg_info = NULL;
512
0
  struct sc_asn1_entry asn1_alg_id[3];
513
0
  int r;
514
515
0
  LOG_FUNC_CALLED(ctx);
516
0
  sc_copy_asn1_entry(c_asn1_alg_id, asn1_alg_id);
517
0
  sc_format_asn1_entry(asn1_alg_id + 0, &id->oid, NULL, 0);
518
519
0
  memset(id, 0, sizeof(*id));
520
0
  r = _sc_asn1_decode(ctx, asn1_alg_id, in, len, &in, &len, 0, depth + 1);
521
0
  LOG_TEST_RET(ctx, r, "ASN.1 parsing of algo ID failed");
522
523
0
        sc_log(ctx, "decoded OID '%s'", sc_dump_oid(&(id->oid)));
524
525
  /* See if we understand the algorithm, and if we do, check
526
   * whether we know how to decode any additional parameters */
527
0
  id->algorithm = (unsigned int ) -1;
528
0
  alg_info = sc_asn1_get_algorithm_info(id);
529
0
  if (alg_info != NULL) {
530
0
    id->algorithm = alg_info->id;
531
0
    if (alg_info->decode) {
532
0
      if (asn1_alg_id[1].flags & SC_ASN1_PRESENT) {
533
0
        sc_log(ctx, "SC_ASN1_PRESENT was set, so invalid");
534
0
        LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT);
535
0
      }
536
0
      r = alg_info->decode(ctx, &id->params, in, len, depth);
537
0
    }
538
0
  }
539
540
0
  LOG_FUNC_RETURN(ctx, r);
541
0
}
542
543
int
544
sc_asn1_encode_algorithm_id(struct sc_context *ctx, u8 **buf, size_t *len,
545
          const struct sc_algorithm_id *id,
546
          int depth)
547
0
{
548
0
  struct sc_asn1_pkcs15_algorithm_info *alg_info;
549
0
  struct sc_algorithm_id temp_id;
550
0
  struct sc_asn1_entry asn1_alg_id[3];
551
0
  u8 *obj = NULL;
552
0
  size_t obj_len = 0;
553
0
  int r;
554
0
  u8 *tmp;
555
556
0
  LOG_FUNC_CALLED(ctx);
557
0
        sc_log(ctx, "type of algorithm to encode: %lu", id->algorithm);
558
0
  alg_info = sc_asn1_get_algorithm_info(id);
559
0
  if (alg_info == NULL) {
560
0
    sc_log(ctx, "Cannot encode unknown algorithm %lu", id->algorithm);
561
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
562
0
  }
563
564
  /* Set the oid if not yet given */
565
0
  if (!sc_valid_oid(&id->oid)) {
566
0
    temp_id = *id;
567
0
    temp_id.oid = alg_info->oid;
568
0
    id = &temp_id;
569
0
  }
570
571
0
        sc_log(ctx, "encode algo %s", sc_dump_oid(&(id->oid)));
572
0
  sc_copy_asn1_entry(c_asn1_alg_id, asn1_alg_id);
573
0
  sc_format_asn1_entry(asn1_alg_id + 0, (void *) &id->oid, NULL, 1);
574
575
  /* no parameters, write NULL tag */
576
  /* If it's EDDSA/XEDDSA, according to RFC8410, params
577
   * MUST be absent */
578
  /* PKCS11 3.0 list them under ec_params */
579
0
  if (id->algorithm != SC_ALGORITHM_EDDSA &&
580
0
      id->algorithm != SC_ALGORITHM_XEDDSA &&
581
0
      (!id->params || !alg_info->encode))
582
0
    asn1_alg_id[1].flags |= SC_ASN1_PRESENT;
583
584
0
  r = _sc_asn1_encode(ctx, asn1_alg_id, buf, len, depth + 1);
585
0
  LOG_TEST_RET(ctx, r, "ASN.1 encode of algorithm failed");
586
587
  /* Encode any parameters */
588
0
  if (id->params && alg_info->encode) {
589
0
    r = alg_info->encode(ctx, id->params, &obj, &obj_len, depth+1);
590
0
    if (r < 0) {
591
0
      if (obj)
592
0
        free(obj);
593
0
      LOG_FUNC_RETURN(ctx, r);
594
0
    }
595
0
  }
596
597
0
  if (obj_len) {
598
0
    tmp = (u8 *) realloc(*buf, *len + obj_len);
599
0
    if (!tmp) {
600
0
      free(*buf);
601
0
      *buf = NULL;
602
0
      free(obj);
603
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
604
0
    }
605
0
    *buf = tmp;
606
0
    memcpy(*buf + *len, obj, obj_len);
607
0
    *len += obj_len;
608
0
    free(obj);
609
0
  }
610
611
0
  sc_log(ctx, "return encoded algorithm ID: %s", sc_dump_hex(*buf, *len));
612
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
613
0
}
614
615
void
616
sc_asn1_clear_algorithm_id(struct sc_algorithm_id *id)
617
0
{
618
0
  struct sc_asn1_pkcs15_algorithm_info *aip;
619
620
0
  if (id->params && (aip = sc_asn1_get_algorithm_info(id)) && aip->free) {
621
0
    aip->free(id->params);
622
0
    id->params = NULL;
623
0
  }
624
0
}