Coverage Report

Created: 2026-04-12 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-openpgp.c
Line
Count
Source
1
/*
2
 * PKCS15 emulation layer for OpenPGP card.
3
 * To see how this works, run p15dump on your OpenPGP card.
4
 *
5
 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
26
#include <stdlib.h>
27
#include <string.h>
28
#include <stdio.h>
29
#include <assert.h>
30
31
#include "common/compat_strlcpy.h"
32
#include "internal.h"
33
#include "pkcs15.h"
34
#include "log.h"
35
#include "card-openpgp.h"
36
37
static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *);
38
39
40
#define PGP_USER_PIN_FLAGS  (SC_PKCS15_PIN_FLAG_CASE_SENSITIVE \
41
        | SC_PKCS15_PIN_FLAG_INITIALIZED \
42
        | SC_PKCS15_PIN_FLAG_LOCAL)
43
#define PGP_ADMIN_PIN_FLAGS (PGP_USER_PIN_FLAGS \
44
        | SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED \
45
        | SC_PKCS15_PIN_FLAG_SO_PIN)
46
47
195
#define PGP_NUM_PRIVDO       4
48
191
#define PGP_MAX_NUM_CERTS    3
49
50
typedef struct _pgp_pin_cfg {
51
  const char  *label;
52
  int   reference;
53
  unsigned int  flags;
54
  int   min_length;
55
  int   do_index;
56
} pgp_pin_cfg_t;
57
58
// clang-format off
59
/* OpenPGP cards v1:
60
 * "Signature PIN2 & "Encryption PIN" are two different PINs - not sync'ed by hardware
61
 */
62
static const pgp_pin_cfg_t  pin_cfg_v1[3] = {
63
  { "Encryption PIN", 0x02, PGP_USER_PIN_FLAGS,  6, 1 },  // used for PSO:DEC, INT-AUT, {GET,PUT} DATA
64
  { "Signature PIN",  0x01, PGP_USER_PIN_FLAGS,  6, 0 },  // used for PSO:CDS
65
  { "Admin PIN",      0x03, PGP_ADMIN_PIN_FLAGS, 8, 2 }
66
};
67
/* OpenPGP cards v2:
68
 * "User PIN (sig)" & "User PIN" are the same PIN, but use different references depending on action
69
 */
70
static const pgp_pin_cfg_t  pin_cfg_v2[3] = {
71
  { "User PIN",       0x02, PGP_USER_PIN_FLAGS,  6, 0 },  // used for PSO:DEC, INT-AUT, {GET,PUT} DATA
72
  { "User PIN (sig)", 0x01, PGP_USER_PIN_FLAGS,  6, 0 },  // used for PSO:CDS
73
  { "Admin PIN",      0x03, PGP_ADMIN_PIN_FLAGS, 8, 2 }
74
};
75
// clang-format on
76
77
static struct sc_object_id curve25519_oid = {{1, 3, 6, 1, 4, 1, 3029, 1, 5, 1, -1}};
78
79
0
#define PGP_SIG_PRKEY_USAGE (SC_PKCS15_PRKEY_USAGE_SIGN \
80
0
        | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER \
81
0
        | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
82
69
#define PGP_ENC_PRKEY_USAGE (SC_PKCS15_PRKEY_USAGE_DECRYPT \
83
69
        | SC_PKCS15_PRKEY_USAGE_UNWRAP)
84
#define PGP_AUTH_PRKEY_USAGE  (SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)
85
86
0
#define PGP_SIG_PUBKEY_USAGE  (SC_PKCS15_PRKEY_USAGE_VERIFY \
87
0
        | SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER)
88
69
#define PGP_ENC_PUBKEY_USAGE  (SC_PKCS15_PRKEY_USAGE_ENCRYPT \
89
69
        | SC_PKCS15_PRKEY_USAGE_WRAP)
90
#define PGP_AUTH_PUBKEY_USAGE (SC_PKCS15_PRKEY_USAGE_VERIFY)
91
92
typedef struct _pgp_key_cfg {
93
  const char  *label;
94
  const char  *pubkey_path;
95
  int   prkey_pin;
96
  int   prkey_usage;
97
  int   pubkey_usage;
98
} pgp_key_cfg_t;
99
100
typedef struct cdata_st {
101
  const char *label;
102
  int     authority;
103
  const char *path;
104
  const char *id;
105
  int         obj_flags;
106
} cdata;
107
108
// clang-format off
109
static const pgp_key_cfg_t key_cfg[3] = {
110
  { "Signature key",      "B601", 1, PGP_SIG_PRKEY_USAGE,  PGP_SIG_PUBKEY_USAGE  },
111
  { "Encryption key",     "B801", 2, PGP_ENC_PRKEY_USAGE,  PGP_ENC_PUBKEY_USAGE  },
112
  { "Authentication key", "A401", 2, PGP_AUTH_PRKEY_USAGE | PGP_ENC_PRKEY_USAGE, PGP_AUTH_PUBKEY_USAGE | PGP_ENC_PUBKEY_USAGE }
113
};
114
115
static const cdata certs[PGP_MAX_NUM_CERTS] = {
116
  {"AUT certificate", 0, "3F007F21", "3", SC_PKCS15_CO_FLAG_MODIFIABLE},
117
  {"DEC certificate", 0, "3F007F21", "2", SC_PKCS15_CO_FLAG_MODIFIABLE},
118
  {"SIG certificate", 0, "3F007F21", "1", SC_PKCS15_CO_FLAG_MODIFIABLE}
119
};
120
// clang-format on
121
122
typedef struct _pgp_manuf_map {
123
  unsigned short    id;
124
  const char  *name;
125
} pgp_manuf_map_t;
126
127
// clang-format off
128
static const pgp_manuf_map_t manuf_map[] = {
129
  { 0x0001, "PPC Card Systems"    },
130
  { 0x0002, "Prism"     },
131
  { 0x0003, "OpenFortress"    },
132
  { 0x0004, "Wewid AB"      },
133
  { 0x0005, "ZeitControl"     },
134
  { 0x0006, "Yubico"      },
135
  { 0x0007, "OpenKMS"     },
136
  { 0x0008, "LogoEmail"     },
137
  { 0x0009, "Fidesmo"     },
138
  { 0x000A, "Dangerous Things"    },
139
  { 0x000B, "Feitian Technologies"  },
140
  { 0x002A, "Magrathea"     },
141
  { 0x0042, "GnuPG e.V."      },
142
  { 0x1337, "Warsaw Hackerspace"    },
143
  { 0x2342, "warpzone"      },
144
  { 0x4354, "Confidential Technologies" },
145
  { 0x5443, "TIF-IT e.V."     },
146
  { 0x63AF, "Trustica"      },
147
  { 0xBA53, "c-base e.V."     },
148
  { 0xBD0E, "Paranoidlabs"    },
149
  { 0xF517, "FSIJ"      },
150
  { 0xF5EC, "F-Secure"      },
151
  { 0x0000, "test card"     },
152
  { 0xffff, "test card"     },
153
  { 0, NULL }
154
};
155
// clang-format on
156
157
/*
158
 * This function pretty much follows what find_tlv in the GNUpg
159
 * code does.
160
 */
161
static int
162
read_file(sc_card_t *card, const char *path_name, void *buf, size_t len)
163
6.32k
{
164
6.32k
  sc_path_t path;
165
6.32k
  sc_file_t *file;
166
6.32k
  int   r;
167
168
6.32k
  sc_format_path(path_name, &path);
169
6.32k
  if ((r = sc_select_file(card, &path, &file)) < 0)
170
3.43k
    return r;
171
172
2.88k
  if (file->size < len)
173
2.76k
    len = file->size;
174
175
2.88k
  sc_file_free(file);
176
177
2.88k
  return sc_read_binary(card, 0, (u8 *) buf, len, 0);
178
6.32k
}
179
180
static int
181
sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
182
3.73k
{
183
3.73k
  sc_card_t *card = p15card->card;
184
3.73k
  sc_context_t  *ctx = card->ctx;
185
3.73k
  struct pgp_priv_data *priv = DRVDATA(card);
186
3.73k
  char    string[256];
187
3.73k
  u8    c4data[10];
188
3.73k
  u8    c5data[100];
189
3.73k
  int   r, i;
190
3.73k
  const pgp_pin_cfg_t *pin_cfg = (card->type == SC_CARD_TYPE_OPENPGP_V1)
191
3.73k
                                 ? pin_cfg_v1 : pin_cfg_v2;
192
3.73k
  sc_path_t path;
193
3.73k
  sc_file_t *file = NULL;
194
195
3.73k
  LOG_FUNC_CALLED(ctx);
196
197
3.73k
  set_string(&p15card->tokeninfo->label, "OpenPGP card");
198
3.73k
  set_string(&p15card->tokeninfo->manufacturer_id, "OpenPGP project");
199
200
  /* card->serialnr = 2 byte manufacturer_id + 4 byte serial_number */
201
3.73k
  if (card->serialnr.len > 0) {
202
2.75k
    unsigned short manuf_id = bebytes2ushort(card->serialnr.value);
203
2.75k
    int j;
204
205
2.75k
    sc_bin_to_hex(card->serialnr.value, card->serialnr.len, string, sizeof(string), 0);
206
2.75k
    set_string(&p15card->tokeninfo->serial_number, string);
207
208
65.0k
    for (j = 0; manuf_map[j].name != NULL; j++) {
209
62.7k
      if (manuf_id == manuf_map[j].id) {
210
476
        set_string(&p15card->tokeninfo->manufacturer_id, manuf_map[j].name);
211
476
        break;
212
476
      }
213
62.7k
    }
214
2.75k
  }
215
216
3.73k
  p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT;
217
218
  /* Extract preferred language */
219
3.73k
  r = read_file(card, "0065:5f2d", string, sizeof(string)-1);
220
3.73k
  if (r < 0)
221
2.98k
    goto failed;
222
751
  string[r] = '\0';
223
751
  set_string(&p15card->tokeninfo->preferred_language, string);
224
225
  /* Get CHV status bytes from DO 006E/0073/00C4:
226
   *  00:   1 == user consent for signature PIN
227
   *    (i.e. PIN still valid for next PSO:CDS command)
228
   *  01-03:  max length of pins 1-3
229
   *  04-07:  tries left for pins 1-3
230
   */
231
751
  sc_log(ctx, "Reading PW status bytes");
232
751
  if ((r = read_file(card, "006E:0073:00C4", c4data, sizeof(c4data))) < 0)
233
330
    goto failed;
234
421
  if (r != 7) {
235
106
    sc_log(ctx, "CHV status bytes have unexpected length (expected 7, got %d)\n", r);
236
106
    r = SC_ERROR_OBJECT_NOT_VALID;
237
106
    goto failed;
238
106
  }
239
240
  /* Add PIN codes */
241
1.26k
  for (i = 0; i < 3; i++) {
242
945
    sc_pkcs15_auth_info_t pin_info;
243
945
    sc_pkcs15_object_t   pin_obj;
244
245
945
    memset(&pin_info, 0, sizeof(pin_info));
246
945
    memset(&pin_obj,  0, sizeof(pin_obj));
247
248
945
    pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
249
945
    pin_info.auth_id.len      = 1;
250
945
    pin_info.auth_id.value[0] = pin_cfg[i].reference;
251
945
    pin_info.attrs.pin.reference     = pin_cfg[i].reference;
252
945
    pin_info.attrs.pin.flags         = pin_cfg[i].flags;
253
945
    pin_info.attrs.pin.type          = SC_PKCS15_PIN_TYPE_UTF8;
254
945
    pin_info.attrs.pin.min_length    = pin_cfg[i].min_length;
255
945
    pin_info.attrs.pin.stored_length = c4data[1 + pin_cfg[i].do_index];
256
945
    pin_info.attrs.pin.max_length    = c4data[1 + pin_cfg[i].do_index];
257
945
    pin_info.attrs.pin.pad_char      = '\0';
258
945
    pin_info.tries_left = c4data[4 + pin_cfg[i].do_index];
259
945
    pin_info.logged_in = SC_PIN_STATE_UNKNOWN;
260
261
945
    sc_format_path("3F00", &pin_info.path);
262
263
945
    strlcpy(pin_obj.label, pin_cfg[i].label, sizeof(pin_obj.label));
264
945
    pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE;
265
945
    if (i < 2) {
266
630
      pin_obj.auth_id.len = 1;
267
630
      pin_obj.auth_id.value[0] = 3;
268
630
    }
269
270
945
    r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
271
945
    if (r < 0) {
272
0
      r = SC_ERROR_INTERNAL;
273
0
      goto failed;
274
0
    }
275
945
  }
276
277
  /* Get private key finger prints from DO 006E/0073/00C5:
278
   *  00-19:  finger print for SIG key
279
   *  20-39:  finger print for ENC key
280
   *  40-59:  finger print for AUT key
281
   */
282
315
  sc_log(ctx, "Reading Fingerprints");
283
315
  if ((r = read_file(card, "006E:0073:00C5", c5data, sizeof(c5data))) < 0)
284
12
    goto failed;
285
303
  if (r < 60) {
286
7
    sc_log(ctx,
287
7
      "finger print bytes have unexpected length (expected 60, got %d)\n", r);
288
7
    r = SC_ERROR_OBJECT_NOT_VALID;
289
7
    goto failed;
290
7
  }
291
292
296
  sc_log(ctx, "Adding private keys");
293
  /* XXX: check if "halfkeys" can be stored with gpg2. If not, add key pairs in one loop */
294
1.00k
  for (i = 0; i < 3; i++) {
295
827
    sc_pkcs15_prkey_info_t prkey_info;
296
827
    sc_pkcs15_object_t     prkey_obj;
297
827
    u8 cxdata[12];
298
827
    int cxdata_len = sizeof(cxdata);
299
827
    char path_template[] = "006E:0073:00Cx";
300
827
    int j;
301
302
827
    memset(&prkey_info, 0, sizeof(prkey_info));
303
827
    memset(&prkey_obj,  0, sizeof(prkey_obj));
304
827
    memset(&cxdata, 0, sizeof(cxdata));
305
306
827
    path_template[13] = '1' + i; /* The needed tags are C1 C2 and C3 */
307
827
    if ((cxdata_len = read_file(card, path_template, cxdata, sizeof(cxdata))) < 1)
308
110
      goto failed;
309
310
    /* check validity using finger prints */
311
2.79k
    for (j = 19; j >= 0; j--) {
312
2.76k
      if (c5data[20 * i + j] != '\0')
313
683
        break;
314
2.76k
    }
315
316
    /* only add valid keys, i.e. those with a legal algorithm identifier & finger print */
317
717
    if (j >= 0 && cxdata[0] != 0) {
318
626
      struct sc_object_id oid = {0};
319
626
      struct sc_algorithm_info * algorithm_info; /* no need to free */
320
321
626
      algorithm_info = NULL;
322
626
      prkey_info.id.len         = 1;
323
626
      prkey_info.id.value[0]    = i + 1;
324
626
      prkey_info.usage          = key_cfg[i].prkey_usage;
325
626
      prkey_info.native         = 1;
326
626
      prkey_info.key_reference  = i;
327
328
626
      strlcpy(prkey_obj.label, key_cfg[i].label, sizeof(prkey_obj.label));
329
626
      prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | SC_PKCS15_CO_FLAG_MODIFIABLE;
330
626
      prkey_obj.auth_id.len      = 1;
331
626
      prkey_obj.auth_id.value[0] = key_cfg[i].prkey_pin;
332
333
      /* need to get size from algorithms using oid */
334
626
      if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH ||
335
553
        cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA ||
336
502
        cxdata[0] == SC_OPENPGP_KEYALGO_EDDSA) {
337
        /* Last byte could be Import-Format of private key, let's ignore it,
338
         * as it is not part of OID */
339
146
        if (cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STD ||
340
92
            cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB)
341
67
          cxdata_len--;
342
146
        r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid);
343
146
        if (r != SC_SUCCESS) {
344
68
          sc_log(ctx, "Failed to parse OID for elliptic curve algorithm");
345
68
        }
346
146
      }
347
348
626
      switch (cxdata[0]) {
349
73
      case SC_OPENPGP_KEYALGO_ECDH:
350
73
        if (sc_compare_oid(&oid, &curve25519_oid)) {
351
0
          if ((algorithm_info = sc_card_find_xeddsa_alg(card, 0, &oid)))
352
0
            prkey_info.field_length = algorithm_info->key_length;
353
0
          else {
354
0
            sc_log(ctx, "algorithm not found");
355
0
            continue;
356
0
          }
357
0
          break;
358
0
        }
359
        /* Fall through */
360
124
      case SC_OPENPGP_KEYALGO_ECDSA:
361
124
        if((algorithm_info = sc_card_find_ec_alg(card, 0, &oid)))
362
0
          prkey_info.field_length = algorithm_info->key_length;
363
124
        else {
364
124
          sc_log(ctx, "algorithm not found");
365
124
          continue;
366
124
        }
367
0
        break;
368
22
      case SC_OPENPGP_KEYALGO_EDDSA:
369
22
        if ((algorithm_info = sc_card_find_eddsa_alg(card, 0, &oid)))
370
0
          prkey_info.field_length = algorithm_info->key_length;
371
22
        else {
372
22
          sc_log(ctx, "algorithm not found");
373
22
          continue;
374
22
        }
375
0
        break;
376
626
      }
377
378
480
      switch (cxdata[0]) {
379
0
      case SC_OPENPGP_KEYALGO_EDDSA:
380
        /* Filter out invalid usage: EdDSA does not support anything but sign */
381
0
        prkey_info.usage &= PGP_SIG_PRKEY_USAGE;
382
0
        r = sc_pkcs15emu_add_eddsa_prkey(p15card, &prkey_obj, &prkey_info);
383
0
        break;
384
385
0
      case SC_OPENPGP_KEYALGO_ECDH:
386
        /* This can result in either ECDSA key or EC_MONTGOMERY
387
         * so we need to check OID */
388
0
        if (sc_compare_oid(&oid, &curve25519_oid)) {
389
          /* This can do only DERIVE */
390
0
          prkey_info.usage = SC_PKCS15_PRKEY_USAGE_DERIVE;
391
0
          r = sc_pkcs15emu_add_xeddsa_prkey(p15card, &prkey_obj, &prkey_info);
392
0
          break;
393
0
        }
394
0
        prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
395
0
        prkey_info.usage &= ~PGP_ENC_PRKEY_USAGE;
396
0
        r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
397
0
        break;
398
399
0
      case SC_OPENPGP_KEYALGO_ECDSA:
400
0
        prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN;
401
0
        r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
402
0
        break;
403
404
306
      case SC_OPENPGP_KEYALGO_RSA:
405
306
        if (cxdata_len >= 3) {
406
          /* with Authentication key, can only decrypt if can change MSE */
407
290
          if (i == 2 && !(priv->ext_caps & EXT_CAP_MSE)) {
408
69
            prkey_info.usage &= ~PGP_ENC_PRKEY_USAGE;
409
69
          }
410
290
          prkey_info.modulus_length = bebytes2ushort(cxdata + 1);
411
290
          r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
412
290
          break;
413
290
        }
414
        /* Fallthrough */
415
190
      default:
416
190
        sc_log(ctx, "Invalid algorithm identifier %x (length = %d)",
417
480
          cxdata[0], r);
418
480
      }
419
420
480
      if (r < 0) {
421
5
        r = SC_ERROR_INTERNAL;
422
5
        goto failed;
423
5
      }
424
480
    }
425
717
  }
426
427
181
  sc_log(ctx, "Adding public keys");
428
  /* Add public keys */
429
713
  for (i = 0; i < 3; i++) {
430
536
    sc_pkcs15_pubkey_info_t pubkey_info;
431
536
    sc_pkcs15_object_t      pubkey_obj;
432
536
    u8 cxdata[12];
433
536
    int cxdata_len = sizeof(cxdata);
434
536
    char path_template[] = "006E:0073:00Cx";
435
536
    int j;
436
437
536
    memset(&pubkey_info, 0, sizeof(pubkey_info));
438
536
    memset(&pubkey_obj,  0, sizeof(pubkey_obj));
439
536
    memset(&cxdata, 0, sizeof(cxdata));
440
441
536
    path_template[13] = '1' + i; /* The needed tags are C1 C2 and C3 */
442
536
    if ((cxdata_len = read_file(card, path_template, cxdata, sizeof(cxdata))) < 1)
443
0
      goto failed;
444
445
    /* check validity using finger prints */
446
1.60k
    for (j = 19; j >= 0; j--) {
447
1.58k
      if (c5data[20 * i + j] != '\0')
448
520
        break;
449
1.58k
    }
450
451
    /* only add valid keys, i.e. those with a legal algorithm identifier & finger print */
452
536
    if (j >= 0 && cxdata[0] != 0) {
453
470
      struct sc_object_id oid;
454
470
      struct sc_algorithm_info * algorithm_info; /* no need to free */
455
456
470
      algorithm_info = NULL;
457
470
      pubkey_info.id.len         = 1;
458
470
      pubkey_info.id.value[0]    = i + 1;
459
470
      pubkey_info.usage          = key_cfg[i].pubkey_usage;
460
470
      sc_format_path(key_cfg[i].pubkey_path, &pubkey_info.path);
461
462
470
      strlcpy(pubkey_obj.label, key_cfg[i].label, sizeof(pubkey_obj.label));
463
470
      pubkey_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
464
465
470
      if (cxdata[0] == SC_OPENPGP_KEYALGO_ECDH ||
466
416
        cxdata[0] == SC_OPENPGP_KEYALGO_ECDSA ||
467
376
        cxdata[0] == SC_OPENPGP_KEYALGO_EDDSA) {
468
        /* Last byte could be Import-Format of private key, let's ignore it,
469
         * as it is not part of OID */
470
112
        if (cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STD ||
471
68
            cxdata[cxdata_len-1] == SC_OPENPGP_KEYFORMAT_EC_STDPUB)
472
53
          cxdata_len--;
473
112
        r = sc_asn1_decode_object_id(&cxdata[1], cxdata_len-1, &oid);
474
112
        if (r != SC_SUCCESS) {
475
48
          sc_log(ctx, "Failed to parse OID for elliptic curve algorithm");
476
48
        }
477
112
      }
478
479
470
      switch (cxdata[0]) {
480
54
      case SC_OPENPGP_KEYALGO_ECDH:
481
54
        if (sc_compare_oid(&oid, &curve25519_oid)) {
482
0
          if ((algorithm_info = sc_card_find_xeddsa_alg(card, 0, &oid)))
483
0
            pubkey_info.field_length = algorithm_info->key_length;
484
0
          else {
485
0
            sc_log(ctx, "algorithm not found");
486
0
            continue;
487
0
          }
488
0
          break;
489
0
        }
490
        /* Fall through */
491
94
      case SC_OPENPGP_KEYALGO_ECDSA:
492
94
        if((algorithm_info = sc_card_find_ec_alg(card, 0, &oid)))
493
0
          pubkey_info.field_length = algorithm_info->key_length;
494
94
        else {
495
94
          sc_log(ctx, "algorithm not found");
496
94
          continue;
497
94
        }
498
0
        break;
499
18
      case SC_OPENPGP_KEYALGO_EDDSA:
500
18
        if ((algorithm_info = sc_card_find_eddsa_alg(card, 0, &oid)))
501
0
          pubkey_info.field_length = algorithm_info->key_length;
502
18
        else {
503
18
          sc_log(ctx, "algorithm not found");
504
18
          continue;
505
18
        }
506
0
        break;
507
470
      }
508
509
358
      switch (cxdata[0]) {
510
0
      case SC_OPENPGP_KEYALGO_EDDSA:
511
        /* assuming Ed25519 as it is the only supported now */
512
        /* Filter out invalid usage: ED does not support anything but sign */
513
0
        pubkey_info.usage &= PGP_SIG_PUBKEY_USAGE;
514
0
        r = sc_pkcs15emu_add_eddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
515
0
        break;
516
0
      case SC_OPENPGP_KEYALGO_ECDH:
517
        /* This can result in either ECDSA key or EC_MONTGOMERY
518
         * so we need to check OID */
519
0
        if (sc_compare_oid(&oid, &curve25519_oid)) {
520
          /* XXX What can this key do? */
521
0
          pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_DERIVE;
522
0
          r = sc_pkcs15emu_add_xeddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
523
0
          break;
524
0
        }
525
0
        pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_DERIVE;
526
0
        r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
527
0
        break;
528
0
      case SC_OPENPGP_KEYALGO_ECDSA:
529
0
        pubkey_info.usage = PGP_SIG_PUBKEY_USAGE;
530
0
        r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
531
0
        break;
532
227
      case SC_OPENPGP_KEYALGO_RSA:
533
227
        if (cxdata_len >= 3) {
534
          /* with Authentication pubkey, can only encrypt if can change MSE */
535
213
          if (i == 2 && !(priv->ext_caps & EXT_CAP_MSE)) {
536
69
            pubkey_info.usage &= ~PGP_ENC_PUBKEY_USAGE;
537
69
          }
538
213
          pubkey_info.modulus_length = bebytes2ushort(cxdata + 1);
539
213
          r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
540
213
          break;
541
213
        }
542
        /* Fall through */
543
145
      default:
544
145
        sc_log(ctx, "Invalid algorithm identifier %x (length = %d)",
545
358
          cxdata[0], r);
546
358
      }
547
548
358
      if (r < 0) {
549
4
        r = SC_ERROR_INTERNAL;
550
4
        goto failed;
551
4
      }
552
358
    }
553
536
  }
554
555
  /* Check if certificate DO 7F21 holds data */
556
177
  sc_format_path("7F21", &path);
557
177
  r = sc_select_file(card, &path, &file);
558
177
  if (r < 0)
559
37
    goto failed;
560
561
191
  for(u8 i=0; i<PGP_MAX_NUM_CERTS; i++) {
562
185
    struct sc_pkcs15_cert_info cert_info;
563
185
    struct sc_pkcs15_object    cert_obj;
564
185
    u8* buffer = malloc(MAX_OPENPGP_DO_SIZE);
565
185
    int resp_len = 0;
566
567
185
    if (buffer == NULL)
568
0
      goto failed;
569
570
185
    memset(&cert_info, 0, sizeof(cert_info));
571
185
    memset(&cert_obj,  0, sizeof(cert_obj));
572
573
    /* try to SELECT DATA. Will only work for OpenPGP >= v3, errors are non-critical */
574
185
    sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
575
576
185
    sc_format_path(certs[i].path, &cert_info.path);
577
578
    /* Certificate ID. We use the same ID as the authentication key */
579
185
    sc_pkcs15_format_id(certs[i].id, &cert_info.id);
580
581
185
    resp_len = sc_get_data(card, 0x7F21, buffer, MAX_OPENPGP_DO_SIZE);
582
583
    /* Response length => free buffer and continue with next id */
584
185
    if (resp_len == 0) {
585
39
      free(buffer);
586
39
      continue;
587
39
    }
588
589
    /* Catch error during sc_get_data */
590
146
    if (resp_len < 0) {
591
101
      free(buffer);
592
101
      goto failed;
593
101
    }
594
595
    /* Assemble certificate info struct, based on `certs` array */
596
45
    cert_info.value.len = resp_len;
597
45
    cert_info.value.value = buffer;
598
45
    cert_info.authority = certs[i].authority;
599
45
    cert_obj.flags = certs[i].obj_flags;
600
601
    /* Object label */
602
45
    strlcpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label));
603
604
45
    r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
605
45
    if (r < 0) {
606
0
      free(buffer);
607
0
      goto failed;
608
0
    }
609
610
    /* only iterate, for OpenPGP >= v3, thus break on < v3 */
611
45
    if (card->type < SC_CARD_TYPE_OPENPGP_V3)
612
33
      break;
613
45
  }
614
615
  /* Add PKCS#15 DATA objects from other OpenPGP card DOs. The return
616
   * value is ignored, so this will not cause initialization to fail.
617
   */
618
39
  sc_pkcs15emu_openpgp_add_data(p15card);
619
620
3.73k
failed:
621
3.73k
  if (r < 0) {
622
3.49k
    sc_log(card->ctx,
623
3.49k
        "Failed to initialize OpenPGP emulation: %s\n",
624
3.49k
        sc_strerror(r));
625
3.49k
    sc_pkcs15_card_clear(p15card);
626
3.49k
  }
627
3.73k
  sc_file_free(file);
628
3.73k
  LOG_FUNC_RETURN(ctx, r);
629
3.73k
}
630
631
// see https://stackoverflow.com/a/10536254 for explanation
632
#define LEN_MAX_INT_AS_STR (3 * sizeof(int) + 2)
633
634
static int
635
sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card)
636
39
{
637
39
  sc_context_t *ctx = p15card->card->ctx;
638
39
  int i, r;
639
640
39
  LOG_FUNC_CALLED(ctx);
641
  /* Optional private use DOs 0101 to 0104 */
642
195
  for (i = 1; i <= PGP_NUM_PRIVDO; i++) {
643
156
    sc_pkcs15_data_info_t dat_info;
644
156
    sc_pkcs15_object_t dat_obj;
645
156
    char name[6 + LEN_MAX_INT_AS_STR];
646
156
    char path[7 + LEN_MAX_INT_AS_STR];
647
156
    u8 content[254];
648
156
    memset(&dat_info, 0, sizeof(dat_info));
649
156
    memset(&dat_obj, 0, sizeof(dat_obj));
650
651
156
    snprintf(name, 8, "PrivDO%d", i);
652
156
    snprintf(path, 9, "3F00010%d", i);
653
654
    /* Check if the DO can be read and is not empty. Otherwise we
655
     * won't expose a PKCS#15 DATA object.
656
     */
657
156
    r = read_file(p15card->card, path, content, sizeof(content));
658
156
    if (r <= 0 ) {
659
85
      sc_log(ctx, "Cannot read DO 010%d or there is no data in it", i);
660
      /* Skip */
661
85
      continue;
662
85
    }
663
71
    sc_format_path(path, &dat_info.path);
664
71
    strlcpy(dat_obj.label, name, sizeof(dat_obj.label));
665
71
    strlcpy(dat_info.app_label, name, sizeof(dat_info.app_label));
666
667
    /* Add DATA object to slot protected by PIN2 (PW1 with Ref 0x82) */
668
71
    dat_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | SC_PKCS15_CO_FLAG_MODIFIABLE;
669
71
    dat_obj.auth_id.len = 1;
670
71
    if (i == 1 || i == 3)
671
37
      dat_obj.auth_id.value[0] = 2;
672
34
    else
673
34
      dat_obj.auth_id.value[0] = 3;
674
675
71
    sc_log(ctx, "Add %s data object", name);
676
71
    r = sc_pkcs15emu_add_data_object(p15card, &dat_obj, &dat_info);
677
71
    LOG_TEST_RET(ctx, r, "Could not add data object to framework");
678
71
  }
679
39
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
680
39
}
681
682
static int openpgp_detect_card(sc_pkcs15_card_t *p15card)
683
65.4k
{
684
65.4k
  if (p15card->card->type == SC_CARD_TYPE_OPENPGP_BASE
685
61.9k
      || p15card->card->type == SC_CARD_TYPE_OPENPGP_V1
686
61.9k
      || p15card->card->type == SC_CARD_TYPE_OPENPGP_V2
687
61.9k
      || p15card->card->type == SC_CARD_TYPE_OPENPGP_GNUK
688
61.7k
      || p15card->card->type == SC_CARD_TYPE_OPENPGP_V3)
689
3.73k
    return SC_SUCCESS;
690
61.7k
  else
691
61.7k
    return SC_ERROR_WRONG_CARD;
692
65.4k
}
693
694
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
695
65.4k
{
696
65.4k
  if (openpgp_detect_card(p15card))
697
61.7k
    return SC_ERROR_WRONG_CARD;
698
3.73k
  return sc_pkcs15emu_openpgp_init(p15card);
699
65.4k
}