Coverage Report

Created: 2025-07-01 06:08

/src/opensc/src/pkcs15init/pkcs15-gids.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkcs15-gids.c: Support for GIDS smart cards.
3
 *
4
 * Copyright (C) 2015 Vincent Le Toux (My Smart Logon) <vincent.letoux@mysmartlogon.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
#ifdef HAVE_CONFIG_H
22
#include "config.h"
23
#endif
24
25
#include <sys/types.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <assert.h>
29
#include <stdarg.h>
30
31
#include "../libopensc/log.h"
32
#include "../libopensc/opensc.h"
33
#include "../libopensc/cardctl.h"
34
#include "../libopensc/asn1.h"
35
#include "pkcs15-init.h"
36
#include "profile.h"
37
38
#include "../libopensc/card-gids.h"
39
40
/*
41
 * Select a key reference.
42
 */
43
static int
44
gids_select_key_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
45
                               sc_pkcs15_prkey_info_t *key_info)
46
0
{
47
0
  sc_card_t *card = p15card->card;
48
0
  LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_SELECT_KEY_REFERENCE, key_info));
49
0
}
50
51
/*
52
 * Create a new key file.
53
 */
54
static int
55
gids_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj)
56
0
{
57
0
  sc_card_t *card = p15card->card;
58
0
  LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_CREATE_KEY, obj));
59
0
}
60
61
62
/*
63
 * Generate a new key.
64
 */
65
static int
66
gids_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
67
                       sc_pkcs15_object_t *obj,
68
                       sc_pkcs15_pubkey_t *pubkey)
69
0
{
70
0
  sc_card_t *card = p15card->card;
71
0
  struct sc_cardctl_gids_genkey call = {obj, pubkey};
72
0
  LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_GENERATE_KEY, &call));
73
0
}
74
75
/*
76
 * Store a usable private key on the card.
77
 */
78
static int
79
gids_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *object,
80
                    sc_pkcs15_prkey_t *key)
81
0
{
82
0
  sc_card_t *card = p15card->card;
83
  
84
0
  struct sc_cardctl_gids_importkey call = {object, key};
85
0
  LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_IMPORT_KEY, &call));
86
0
}
87
88
static int 
89
gids_delete_object(struct sc_profile *profile, struct sc_pkcs15_card * p15card,
90
0
      struct sc_pkcs15_object *object, const struct sc_path *path) {
91
0
  sc_card_t *card = p15card->card;
92
0
  switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
93
0
  case SC_PKCS15_TYPE_PRKEY:
94
0
    LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_DELETE_KEY, object));
95
0
    break;
96
0
  case SC_PKCS15_TYPE_CERT:
97
0
    LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_DELETE_CERT, object));
98
0
    break;
99
0
  case SC_PKCS15_TYPE_PUBKEY:
100
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
101
0
  default:
102
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
103
0
  }
104
0
}
105
106
static int gids_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
107
    unsigned op, struct sc_pkcs15_object *object)
108
0
{
109
0
  LOG_FUNC_CALLED(p15card->card->ctx);
110
  /* After storing object, pkcs15init will call this function to update DF.
111
   * But GIDS has no other DF than GIDS-Application, so we do nothing. */
112
0
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
113
0
}
114
115
0
static int gids_save_certificate(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_path *path) {
116
0
  int r;
117
0
  sc_card_t *card = p15card->card;
118
0
  struct sc_cardctl_gids_save_cert call = {object, NULL, path};
119
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
120
121
0
  r = sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, &cert_info->id , &(call.privkeyobject));
122
0
  if (r == SC_ERROR_OBJECT_NOT_FOUND) {
123
    //TODO save the certificate in the special file
124
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
125
0
  }
126
0
  LOG_TEST_RET(card->ctx, r, "unable to find the private key associated to the certificate");
127
128
0
  LOG_FUNC_RETURN(card->ctx, sc_card_ctl(card, SC_CARDCTL_GIDS_SAVE_CERT, &call));
129
0
}
130
131
static int gids_emu_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
132
                              struct sc_pkcs15_object *object,  struct sc_pkcs15_der *content,
133
0
                              struct sc_path *path) {
134
0
  sc_card_t *card = p15card->card;
135
0
  int r;
136
137
0
  LOG_FUNC_CALLED(card->ctx);
138
139
0
  switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) {
140
0
  case SC_PKCS15_TYPE_PRKEY:
141
0
  case SC_PKCS15_TYPE_PUBKEY:
142
    /* For these two type, store_data just don't need to do anything.
143
     * All have been done already before this function is called */
144
0
    r = SC_SUCCESS;
145
0
    break;
146
0
  case SC_PKCS15_TYPE_CERT:
147
0
    r = gids_save_certificate(p15card, object, path);
148
0
    break;
149
0
  default:
150
0
    r = SC_ERROR_NOT_IMPLEMENTED;
151
0
    break;
152
0
  }
153
0
  LOG_FUNC_RETURN(card->ctx, r);
154
0
}
155
156
static int gids_emu_update_tokeninfo(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
157
                    sc_pkcs15_tokeninfo_t *tokeninfo)
158
0
{
159
0
  LOG_FUNC_CALLED(p15card->card->ctx);
160
  /* When unbinding pkcs15init, this function will be called.
161
   * But for GIDS, token info does not need to change, we do nothing. */
162
0
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
163
0
}
164
165
static struct sc_pkcs15init_operations sc_pkcs15init_gids_operations =
166
{
167
  NULL,                           /* erase_card */
168
  NULL,                           /* init_card */
169
  NULL,                           /* create_dir */
170
  NULL,                           /* create_domain */
171
  NULL,                           /* pin_reference*/
172
  NULL,                           /* create_pin */
173
  gids_select_key_reference, /* key_reference */
174
  gids_create_key,           /* create_key */
175
  gids_store_key,            /* store_key */
176
  gids_generate_key,         /* generate_key */
177
  NULL, NULL,                     /* encode private/public key */
178
  NULL,                           /* finalize */
179
  gids_delete_object,                           /* delete_object */
180
  NULL, /* pkcs15init emulation emu_update_dir */
181
  gids_emu_update_any_df, /* pkcs15init emulation emu_update_any_df */
182
  gids_emu_update_tokeninfo, /* pkcs15init emulation emu_update_tokeninfo */
183
  NULL, /* pkcs15init emulation emu_write_info */
184
  gids_emu_store_data, /* pkcs15init emulation emu_store_data */
185
  NULL,                           /* sanity_check*/
186
};
187
188
struct
189
sc_pkcs15init_operations *sc_pkcs15init_get_gids_ops(void)
190
0
{
191
0
  return &sc_pkcs15init_gids_operations;
192
0
}