Coverage Report

Created: 2025-07-18 06:10

/src/opensc/src/pkcs15init/pkcs15-openpgp.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * OpenPGP specific operation for PKCS15 initialization
3
 *
4
 * Copyright (c) 2012  Nguyen Hong Quan <ng.hong.quan@gmail.com>.
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
#include "config.h"
22
23
#include <sys/types.h>
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include "libopensc/opensc.h"
28
#include "libopensc/cardctl.h"
29
#include "libopensc/internal.h"
30
#include "libopensc/log.h"
31
#include "libopensc/cards.h"
32
#include "libopensc/asn1.h"
33
#include "pkcs15-init.h"
34
#include "profile.h"
35
36
37
/**
38
 * Erase card: erase all EFs/DFs created by OpenSC
39
 * @param  profile  The sc_profile_t object with the configurable profile
40
 *                  information
41
 * @param  p15card  The card from which the opensc application should be
42
 *                  erased.
43
 * @return SC_SUCCESS on success and an error code otherwise
44
 **/
45
static int openpgp_erase(struct sc_profile *profile, sc_pkcs15_card_t *p15card)
46
0
{
47
0
  return SC_ERROR_NOT_SUPPORTED;
48
0
}
49
50
/**
51
 * Create application DF
52
 * @param  profile  sc_profile_t object with the configurable profile
53
 *                  information
54
 * @param  p15card  sc_card_t object to be used
55
 * @param  df       sc_file_t with the application DF to create
56
 * @return SC_SUCCESS on success and an error value otherwise
57
 **/
58
static int openpgp_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
59
  sc_file_t *df)
60
0
{
61
0
  return SC_ERROR_NOT_SUPPORTED;
62
0
}
63
64
/**
65
 * Select PIN reference: do nothing special, the real PIN reference if
66
 * determined when the PIN is created. This is just helper function to
67
 * determine the next best file id of the PIN file.
68
 **/
69
static int openpgp_select_pin_reference(sc_profile_t *profile,
70
    sc_pkcs15_card_t *p15card, sc_pkcs15_auth_info_t *auth_info)
71
0
{
72
0
  return SC_ERROR_NOT_SUPPORTED;
73
0
}
74
75
/**
76
 * Create PIN and, if specified, PUK files
77
 * @param  profile  profile information for this card
78
 * @param  card     sc_card_t object to use
79
 * @param  pin_obj  sc_pkcs15_object_t for the PIN
80
 * @param  pin      PIN value
81
 * @param  len_len  PIN length
82
 * @param  puk      PUK value (optional)
83
 * @param  puk_len  PUK length (optional)
84
 * @return SC_SUCCESS on success and an error code otherwise
85
 **/
86
static int openpgp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
87
  sc_file_t *df, sc_pkcs15_object_t *pin_obj,
88
  const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len)
89
0
{
90
0
  return SC_ERROR_NOT_SUPPORTED;
91
0
}
92
93
/**
94
 * Creates empty key file
95
 **/
96
static int openpgp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
97
  sc_pkcs15_object_t *obj)
98
0
{
99
  /* For OpenPGP card, the number of keys is fixed,
100
   * so this function does not really do anything.
101
   * It just present here to avoid pkcs15init's default routine,
102
   * which tries to do impossible things. */
103
0
  LOG_FUNC_CALLED(p15card->card->ctx);
104
0
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
105
0
}
106
/**
107
 * Set algorithm and check if card supports it
108
 * @param p15card sc_pkcs15_card_t
109
 * @param type SC_PKCS15_TYPE_*
110
 * @param key_id  openspgp id
111
 * @param &algorithm   SC_OPENPGP_KEYALGO_*
112
113
 * @returns 0 or error
114
 */
115
116
static int
117
openpgp_set_algorithm(sc_pkcs15_card_t *p15card,
118
    u8 key_id, unsigned long type, u8 *algo)
119
0
{
120
0
  sc_card_t *card = p15card->card;
121
122
0
  if (card->type != SC_CARD_TYPE_OPENPGP_GNUK &&
123
0
      card->type < SC_CARD_TYPE_OPENPGP_V3) {
124
0
    sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card");
125
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
126
0
  }
127
128
0
  switch (key_id) {
129
0
  case SC_OPENPGP_KEY_SIGN:
130
0
  case SC_OPENPGP_KEY_AUTH:
131
0
    switch (type) {
132
0
    case SC_PKCS15_TYPE_PRKEY_EC:
133
0
    case SC_PKCS15_TYPE_PUBKEY_EC:
134
0
      *algo = SC_OPENPGP_KEYALGO_ECDSA;
135
0
      return SC_SUCCESS;
136
0
      break;
137
0
    case SC_PKCS15_TYPE_PRKEY_EDDSA:
138
0
    case SC_PKCS15_TYPE_PUBKEY_EDDSA:
139
0
      *algo = SC_OPENPGP_KEYALGO_EDDSA;
140
0
      return SC_SUCCESS;
141
0
      break;
142
0
    }
143
0
    break;
144
0
  case SC_OPENPGP_KEY_ENCR:
145
0
    switch (type) {
146
0
    case SC_PKCS15_TYPE_PRKEY_EC:
147
0
    case SC_PKCS15_TYPE_PUBKEY_EC:
148
0
      *algo = SC_OPENPGP_KEYALGO_ECDH;
149
0
      return SC_SUCCESS;
150
0
      break;
151
0
    case SC_PKCS15_TYPE_PRKEY_XEDDSA:
152
0
    case SC_PKCS15_TYPE_PUBKEY_XEDDSA:
153
0
      *algo = SC_OPENPGP_KEYALGO_ECDH;
154
0
      return SC_SUCCESS;
155
0
      break;
156
0
    }
157
0
    break;
158
0
  }
159
0
  sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Invalid algorithm of openpgp slot");
160
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
161
0
}
162
163
/**
164
 * Stores an external key on the card.
165
 * @param  profile  profile information for this card
166
 * @param  card     sc_card_t object to use
167
 * @param  obj      sc_pkcs15_object_t object with pkcs15 information
168
 * @param  key      the private key
169
 * @return SC_SUCCESS on success and an error code otherwise
170
 **/
171
static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
172
  sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
173
0
{
174
0
  sc_card_t *card = p15card->card;
175
0
  sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
176
0
  sc_cardctl_openpgp_key_gen_store_info_t key_info = {0};
177
0
  int r;
178
179
0
  LOG_FUNC_CALLED(card->ctx);
180
181
0
  switch(obj->type)
182
0
  {
183
0
  case SC_PKCS15_TYPE_PRKEY_RSA:
184
0
    memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t));
185
0
    key_info.algorithm = SC_OPENPGP_KEYALGO_RSA;
186
0
    key_info.key_id = kinfo->id.value[0];
187
0
    key_info.u.rsa.exponent = key->u.rsa.exponent.data;
188
0
    key_info.u.rsa.exponent_len = key->u.rsa.exponent.len * 8; /* use bits instead of bytes */
189
0
    key_info.u.rsa.p = key->u.rsa.p.data;
190
0
    key_info.u.rsa.p_len = key->u.rsa.p.len;
191
0
    key_info.u.rsa.q = key->u.rsa.q.data;
192
0
    key_info.u.rsa.q_len = key->u.rsa.q.len;
193
0
    key_info.u.rsa.modulus = key->u.rsa.modulus.data;
194
0
    key_info.u.rsa.modulus_len = key->u.rsa.modulus.len * 8; /* use bits instead of bytes */
195
0
    r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info);
196
197
    /* nothing to free in key_info for RSA */
198
0
    break;
199
200
0
  case SC_PKCS15_TYPE_PRKEY_EC:
201
0
  case SC_PKCS15_TYPE_PRKEY_EDDSA:
202
0
  case SC_PKCS15_TYPE_PRKEY_XEDDSA:
203
0
    memset(&key_info, 0, sizeof(sc_cardctl_openpgp_key_gen_store_info_t));
204
205
0
    r = openpgp_set_algorithm(p15card, kinfo->id.value[0], obj->type, &key_info.algorithm);
206
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "Key type not valid for key id");
207
208
0
    key_info.key_id = kinfo->id.value[0];
209
0
    key_info.u.ec.privateD = key->u.ec.privateD.data;
210
0
    key_info.u.ec.privateD_len = key->u.ec.privateD.len;
211
    /*
212
     * key->u.ec.ecpointQ.len is optional with private key
213
     * PKCS11 does not pass it when creting private key object.
214
     * pkcs15init/pkcs15-lib.c will attempt to derive it from private key
215
     */
216
0
    if (key->u.ec.ecpointQ.len) {
217
0
      key_info.u.ec.ecpointQ = malloc(key->u.ec.ecpointQ.len);
218
0
      if (!key_info.u.ec.ecpointQ)
219
0
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
220
0
      memcpy(key_info.u.ec.ecpointQ, key->u.ec.ecpointQ.value, key->u.ec.ecpointQ.len);
221
0
    }
222
0
    key_info.u.ec.ecpointQ_len = key->u.ec.ecpointQ.len;
223
0
    key_info.u.ec.oid = key->u.ec.params.id;
224
0
    key_info.key_type = key->algorithm; /* SC_SC_ALGORITHM_* */
225
0
    r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info);
226
227
0
    free(key_info.u.ec.ecpointQ);
228
0
    break;
229
230
0
  default:
231
0
    r = SC_ERROR_NOT_SUPPORTED;
232
0
    sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r));
233
0
  }
234
235
0
err:
236
0
  LOG_FUNC_RETURN(card->ctx, r);
237
0
}
238
239
/**
240
 * Generates a new RSA key pair on card.
241
 * @param  card     IN sc_card_t object to use
242
 * @param  obj      IN sc_pkcs15_object_t object with pkcs15 information
243
 * @param  pukkey   OUT the newly created public key
244
 * @return SC_SUCCESS on success and an error code otherwise
245
 **/
246
static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
247
  sc_pkcs15_pubkey_t *pubkey)
248
0
{
249
0
  sc_context_t *ctx = card->ctx;
250
0
  sc_cardctl_openpgp_key_gen_store_info_t key_info;
251
0
  sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data;
252
0
  sc_pkcs15_id_t *kid = &(required->id);
253
0
  int r;
254
255
0
  LOG_FUNC_CALLED(ctx);
256
0
  memset(&key_info, 0, sizeof(key_info));
257
0
  sc_log(ctx, "Key ID to be generated: %s", sc_dump_hex(kid->value, kid->len));
258
259
  /* Accept KeyID = 45, which is default value set by pkcs15init */
260
0
  if (kid->len == 1 && kid->value[0] == 0x45) {
261
    /* Default key is authentication key. We choose this because the common use
262
     * is to generate from PKCS#11 (Firefox/Thunderbird) */
263
0
    sc_log(ctx, "Authentication key is to be generated.");
264
0
    key_info.key_id = 3;
265
0
  }
266
0
  if (!key_info.key_id && (kid->len > 1 || kid->value[0] > 3)) {
267
0
    sc_log(ctx, "Key ID must be 1, 2 or 3!");
268
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
269
0
  }
270
271
0
  if (!key_info.key_id)
272
0
    key_info.key_id = kid->value[0];
273
274
0
  if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
275
0
    sc_log(card->ctx,  "only RSA is currently supported");
276
0
    return SC_ERROR_NOT_SUPPORTED;
277
0
  }
278
279
280
0
  key_info.algorithm = SC_OPENPGP_KEYALGO_RSA;
281
282
  /* Prepare buffer */
283
0
  key_info.u.rsa.modulus_len = required->modulus_length;
284
0
  key_info.u.rsa.modulus = calloc(1, BYTES4BITS(required->modulus_length));
285
0
  if (key_info.u.rsa.modulus == NULL)
286
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
287
288
  /* The OpenPGP supports only 32-bit exponent. */
289
0
  key_info.u.rsa.exponent_len = 32;
290
0
  key_info.u.rsa.exponent = calloc(1, BYTES4BITS(key_info.u.rsa.exponent_len));
291
0
  if (key_info.u.rsa.exponent == NULL) {
292
0
    free(key_info.u.rsa.modulus);
293
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
294
0
  }
295
296
0
  r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
297
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "on-card EC key generation failed");
298
299
0
  pubkey->algorithm = SC_ALGORITHM_RSA;
300
0
  sc_log(ctx, "Set output modulus info");
301
0
  pubkey->u.rsa.modulus.len = BYTES4BITS(key_info.u.rsa.modulus_len);
302
0
  pubkey->u.rsa.modulus.data = calloc(1, pubkey->u.rsa.modulus.len);
303
0
  if (pubkey->u.rsa.modulus.data == NULL)
304
0
    goto err;
305
0
  memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, BYTES4BITS(key_info.u.rsa.modulus_len));
306
307
0
  sc_log(ctx, "Set output exponent info");
308
0
  pubkey->u.rsa.exponent.len = BYTES4BITS(key_info.u.rsa.exponent_len);
309
0
  pubkey->u.rsa.exponent.data = calloc(1, pubkey->u.rsa.exponent.len);
310
0
  if (pubkey->u.rsa.exponent.data == NULL)
311
0
    goto err;
312
0
  memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, pubkey->u.rsa.exponent.len);
313
314
0
err:
315
0
  free(key_info.u.rsa.modulus);
316
0
  key_info.u.rsa.modulus = NULL;
317
0
  free(key_info.u.rsa.exponent);
318
0
  key_info.u.rsa.exponent = NULL;
319
0
  free(key_info.data);
320
0
  LOG_FUNC_RETURN(ctx, r);
321
0
}
322
323
324
/**
325
 * Generates a new ECC key pair on card.
326
 * @param  card     IN sc_card_t object to use
327
 * @param  obj      IN sc_pkcs15_object_t object with pkcs15 information
328
 * @param  pukkey   OUT the newly created public key
329
 * @return SC_SUCCESS on success and an error code otherwise
330
 **/
331
static int openpgp_generate_key_ec(sc_card_t *card, sc_pkcs15_object_t *obj,
332
                  sc_pkcs15_pubkey_t *pubkey)
333
0
{
334
0
  sc_context_t *ctx = card->ctx;
335
0
  sc_cardctl_openpgp_key_gen_store_info_t key_info;
336
0
  sc_pkcs15_prkey_info_t *required = (sc_pkcs15_prkey_info_t *)obj->data;
337
0
  sc_pkcs15_id_t *kid = &(required->id);
338
0
  struct sc_ec_parameters *info_ec =
339
0
      (struct sc_ec_parameters *)required->params.data;
340
0
  int r;
341
342
0
  LOG_FUNC_CALLED(ctx);
343
0
  memset(&key_info, 0, sizeof(key_info));
344
345
0
  sc_log(ctx, "Key ID to be generated: %s", sc_dump_hex(kid->value, kid->len));
346
347
  /* Accept KeyID = 45, which is default value set by pkcs15init */
348
0
  if (kid->len == 1 && kid->value[0] == 0x45) {
349
    /* Default key is authentication key. We choose this because the common use
350
     * is to generate from PKCS#11 (Firefox/Thunderbird) */
351
0
    sc_log(ctx, "Authentication key is to be generated.");
352
0
    key_info.key_id = 3;
353
0
  }
354
0
  if (!key_info.key_id && (kid->len > 1 || kid->value[0] > 3)) {
355
0
    sc_log(ctx, "Key ID must be 1, 2 or 3!");
356
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
357
0
  }
358
359
0
  if (!key_info.key_id)
360
0
    key_info.key_id = kid->value[0];
361
0
  key_info.key_type = pubkey->algorithm;
362
  /* set algorithm id based on key reference and key type */
363
0
  switch (pubkey->algorithm) {
364
    /* EC is in 04||x||y format
365
     * (field_length + 7)/8 * 2 + 1 in bytes
366
     * len is ecpoint length + format byte
367
     * see section 7.2.14 of 3.3.1 specs
368
     * EDDSA and XEDDSA have no format byte and one number
369
     * (field_length + 7)/8 in bytes
370
     */
371
372
0
  case SC_ALGORITHM_EC:
373
0
    key_info.algorithm = (key_info.key_id == SC_OPENPGP_KEY_ENCR)
374
0
                 ? SC_OPENPGP_KEYALGO_ECDH   /* ECDH for slot 2 only */
375
0
                 : SC_OPENPGP_KEYALGO_ECDSA; /* ECDSA for slot 1 and 3 */
376
0
    key_info.u.ec.ecpointQ_len = 1 + 2 * BYTES4BITS(required->field_length);
377
0
    break;
378
0
  case SC_ALGORITHM_EDDSA:
379
0
    key_info.algorithm = SC_OPENPGP_KEYALGO_EDDSA; /* only sign */
380
0
    key_info.u.ec.ecpointQ_len = BYTES4BITS(required->field_length);
381
0
    break;
382
0
  case SC_ALGORITHM_XEDDSA:
383
    /* TODO  may need to look at MSE, and how sign XEDDSA certificate */
384
0
    key_info.algorithm = SC_OPENPGP_KEYALGO_ECDH; /* but could be used to sign too */
385
0
    key_info.u.ec.ecpointQ_len = BYTES4BITS(required->field_length);
386
0
    break;
387
0
  }
388
389
  /* copying info_ec.id works for any EC ECDH EdDSA keys */
390
0
  if (info_ec->der.len > 2 && info_ec->der.len == (size_t)(info_ec->der.value[1] + 2))
391
0
    key_info.u.ec.oidv_len = info_ec->der.value[1];
392
0
  else
393
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
394
395
0
  for (size_t i = 0; (i < key_info.u.ec.oidv_len) && (i + 2 < info_ec->der.len); i++) {
396
0
    key_info.u.ec.oidv.value[i] = info_ec->der.value[i + 2];
397
0
  }
398
0
  key_info.u.ec.oidv.value[key_info.data_len] = -1;
399
400
  /* copy  id also */
401
0
  key_info.u.ec.oid = info_ec->id;
402
403
  /* generate key on card */
404
0
  r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
405
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "on-card EC key generation failed");
406
407
  /* set pubkey according to response of card */
408
0
  sc_log(ctx, "Set output ecpoint info");
409
410
0
  pubkey->algorithm = key_info.key_type;
411
0
  pubkey->u.ec.ecpointQ.len = key_info.u.ec.ecpointQ_len;
412
0
  pubkey->u.ec.ecpointQ.value = malloc(key_info.u.ec.ecpointQ_len);
413
0
  if (pubkey->u.ec.ecpointQ.value == NULL) {
414
0
    r = SC_ERROR_NOT_ENOUGH_MEMORY;
415
0
    goto err;
416
0
  }
417
418
0
  memcpy(pubkey->u.ec.ecpointQ.value, key_info.u.ec.ecpointQ, key_info.u.ec.ecpointQ_len);
419
420
0
err:
421
0
  free(key_info.u.ec.ecpointQ);
422
423
0
  LOG_FUNC_RETURN(ctx, r);
424
0
}
425
426
427
/**
428
 * Generates a new key pair using an existing key file.
429
 * @param  profile  IN profile information for this card
430
 * @param  card     IN sc_card_t object to use
431
 * @param  obj      IN sc_pkcs15_object_t object with pkcs15 information
432
 * @param  pukkey   OUT the newly created public key
433
 * @return SC_SUCCESS on success and an error code otherwise
434
 **/
435
static int openpgp_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
436
  sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey)
437
0
{
438
0
  sc_card_t *card = p15card->card;
439
0
  sc_context_t *ctx = card->ctx;
440
0
  int r;
441
442
0
  LOG_FUNC_CALLED(ctx);
443
444
0
  switch(obj->type)
445
0
  {
446
0
  case SC_PKCS15_TYPE_PRKEY_RSA:
447
0
    r = openpgp_generate_key_rsa(card, obj, pubkey);
448
0
    break;
449
0
  case SC_PKCS15_TYPE_PRKEY_EC:
450
0
    if (card->type < SC_CARD_TYPE_OPENPGP_V3) {
451
0
      sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is supported on this card");
452
0
      return SC_ERROR_NOT_SUPPORTED;
453
0
    }
454
0
    r = openpgp_generate_key_ec(card, obj, pubkey);
455
0
    break;
456
0
  case SC_PKCS15_TYPE_PRKEY_EDDSA:
457
0
  case SC_PKCS15_TYPE_PRKEY_XEDDSA:
458
0
    if (card->type != SC_CARD_TYPE_OPENPGP_GNUK && card->type < SC_CARD_TYPE_OPENPGP_V3) {
459
0
      sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "EdDSA or XEDDSA are not supported on this card");
460
0
      return SC_ERROR_NOT_SUPPORTED;
461
0
    }
462
0
    r = openpgp_generate_key_ec(card, obj, pubkey);
463
0
    break;
464
0
  default:
465
0
    r = SC_ERROR_NOT_SUPPORTED;
466
0
    sc_log(card->ctx, "%s: Key generation failed: Unknown/unsupported key type.", strerror(r));
467
0
  }
468
469
0
  LOG_FUNC_RETURN(ctx, r);
470
0
}
471
472
static int openpgp_emu_update_any_df(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
473
                   unsigned operation, sc_pkcs15_object_t *obj)
474
0
{
475
0
  LOG_FUNC_CALLED(p15card->card->ctx);
476
  /* After storing object, pkcs15init will call this function to update DF.
477
   * But OpenPGP has no other DF than OpenPGP-Application, so we do nothing. */
478
0
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
479
0
}
480
481
static int openpgp_emu_update_tokeninfo(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
482
                    sc_pkcs15_tokeninfo_t *tokeninfo)
483
0
{
484
0
  LOG_FUNC_CALLED(p15card->card->ctx);
485
  /* When unbinding pkcs15init, this function will be called.
486
   * But for OpenPGP, token info does not need to change, we do nothing. */
487
0
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
488
0
}
489
490
static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
491
                              struct sc_pkcs15_object *obj, struct sc_pkcs15_der *content,
492
                              struct sc_path *path)
493
0
{
494
0
  sc_card_t *card = p15card->card;
495
0
  sc_context_t *ctx = card->ctx;
496
0
  sc_file_t *file = NULL;
497
0
  sc_pkcs15_cert_info_t *cinfo;
498
0
  sc_pkcs15_id_t *cid;
499
0
  sc_pkcs15_data_info_t *dinfo;
500
0
  u8 buf[254];
501
0
  int r;
502
503
0
  LOG_FUNC_CALLED(card->ctx);
504
505
0
  switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
506
0
  case SC_PKCS15_TYPE_PRKEY:
507
0
  case SC_PKCS15_TYPE_PUBKEY:
508
    /* For these two type, store_data just don't need to do anything.
509
     * All have been done already before this function is called */
510
0
    r = SC_SUCCESS;
511
0
    break;
512
513
0
  case SC_PKCS15_TYPE_CERT:
514
0
    cinfo = (sc_pkcs15_cert_info_t *) obj->data;
515
0
    cid = &(cinfo->id);
516
0
    unsigned int tag = 0x7F21;
517
518
0
    if (cid->len != 1) {
519
0
      sc_log(card->ctx, "ID=%s is not valid.", sc_dump_hex(cid->value, cid->len));
520
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
521
0
    }
522
523
    /* OpenPGP card v.2 contains only 1 certificate */
524
0
    if (cid->value[0] != 3 && p15card->card->type < SC_CARD_TYPE_OPENPGP_V3) {
525
0
      sc_log(card->ctx,
526
0
             "This version does not support certificate ID = %d (only ID=3 is supported).",
527
0
             cid->value[0]);
528
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
529
0
    }
530
531
    /* OpenPGP card < v.3 does not support SELECT DATA calls */
532
0
    if (p15card->card->type >= SC_CARD_TYPE_OPENPGP_V3) {
533
      /* Mapping [3..1] passed --id to [0..2] for param */
534
0
      u8 param = (u8) (2 - (cid->value[0] - 1));
535
      /* check for unsigned underflow */
536
0
      if (param > 2) {
537
0
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
538
0
      }
539
540
      /* Just update the certificate DO */
541
0
      r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &param);
542
0
      LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data");
543
0
    }
544
545
0
    sc_format_path("7F21", path);
546
0
    r = sc_select_file(card, path, &file);
547
548
0
    LOG_TEST_RET(card->ctx, r, "Cannot select cert file");
549
0
    r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
550
0
    sc_log(card->ctx,
551
0
           "Data to write is %"SC_FORMAT_LEN_SIZE_T"u long",
552
0
           content->len);
553
0
    if (r >= 0 && content->len)
554
0
      r = sc_put_data(p15card->card, tag, (const unsigned char *) content->value, content->len);
555
0
    break;
556
557
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
558
0
    dinfo = (sc_pkcs15_data_info_t *) obj->data;
559
    /* dinfo->app_label contains filename */
560
0
    sc_log(ctx, "===== App label %s", dinfo->app_label);
561
    /* Currently, we only support DO 0101. The reason is that when initializing this
562
     * pkcs15 emulation, PIN authentication is not applied and we can expose only this DO,
563
     * which is "read always".
564
     * If we support other DOs, they will not be exposed, and not helpful to user.
565
     * I haven't found a way to refresh the list of exposed DOs after verifying PIN yet.
566
     * http://sourceforge.net/mailarchive/message.php?msg_id=30646373
567
     **/
568
0
    sc_log(ctx, "About to write to DO 0101");
569
0
    sc_format_path("0101", path);
570
0
    r = sc_select_file(card, path, &file);
571
0
    LOG_TEST_RET(card->ctx, r, "Cannot select private DO");
572
0
    r = sc_read_binary(card, 0, buf, sizeof(buf), 0);
573
0
    if (r < 0) {
574
0
      sc_log(ctx, "Cannot read DO 0101");
575
0
      break;
576
0
    }
577
0
    if (r > 0) {
578
0
      sc_log(ctx, "DO 0101 is full.");
579
0
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
580
0
      break;
581
0
    }
582
0
    r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
583
0
    if (r >= 0 && content->len) {
584
0
      r = sc_update_binary(p15card->card, 0,
585
0
                           (const unsigned char *) content->value,
586
0
                           content->len, 0);
587
0
    }
588
0
    break;
589
590
0
  default:
591
0
    r = SC_ERROR_NOT_IMPLEMENTED;
592
0
  }
593
594
0
  sc_file_free(file);
595
0
  LOG_FUNC_RETURN(card->ctx, r);
596
0
}
597
598
static struct sc_pkcs15init_operations sc_pkcs15init_openpgp_operations = {
599
    openpgp_erase,
600
    NULL, /* init_card */
601
    openpgp_create_dir,
602
    NULL, /* create_domain */
603
    openpgp_select_pin_reference,
604
    openpgp_create_pin,
605
    NULL, /* select key reference */
606
    openpgp_create_key,
607
    openpgp_store_key,
608
    openpgp_generate_key,
609
    NULL, NULL, /* encode private/public key */
610
    NULL,     /* finalize_card */
611
    NULL,     /* delete_object */
612
    NULL,
613
    openpgp_emu_update_any_df,
614
    openpgp_emu_update_tokeninfo,
615
    NULL,       /* emu_write_info */
616
    openpgp_store_data, /* emu_store_data */
617
    NULL        /* sanity_check */
618
};
619
620
struct sc_pkcs15init_operations *sc_pkcs15init_get_openpgp_ops(void)
621
0
{
622
0
  return &sc_pkcs15init_openpgp_operations;
623
0
}