root/trunk/src/libopensc/p15card-helper.c

Revision 3502, 10.3 KB (checked in by ludovic.rousseau, 7 months ago)

convert C++ in C comment

Line 
1/*
2 * p15card-helper.c: Utility library to assist in PKCS#15 emulation on Non-filesystem cards
3 *
4 * Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include "internal.h"
22
23#if ENABLE_OPENSSL
24#include "p15card-helper.h"
25#include <opensc/opensc.h>
26#include <opensc/types.h>
27#include <opensc/log.h>
28#include <opensc/pkcs15.h>
29#include <string.h>
30#include <stdlib.h>
31#include <openssl/bio.h>
32#include <openssl/rsa.h>
33#include <openssl/x509.h>
34
35int sc_pkcs15emu_initialize_objects(sc_pkcs15_card_t *p15card, p15data_items *items) {
36        sc_card_t* card = p15card->card;
37        const objdata* objects = items->objects;
38        int i, r;
39        if(!objects) return SC_SUCCESS;
40        for (i = 0; objects[i].label; i++) {
41                struct sc_pkcs15_data_info obj_info;
42                struct sc_pkcs15_object    obj_obj;
43
44                memset(&obj_info, 0, sizeof(obj_info));
45                memset(&obj_obj, 0, sizeof(obj_obj));
46                sc_pkcs15_format_id(objects[i].id, &obj_info.id);
47                sc_format_path(objects[i].path, &obj_info.path);
48                strncpy(obj_info.app_label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
49                r = sc_format_oid(&obj_info.app_oid, objects[i].aoid);
50                if (r != SC_SUCCESS)
51                        return r;
52
53                strncpy(obj_obj.label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
54                obj_obj.flags = objects[i].obj_flags;
55               
56                r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT,
57                        &obj_obj, &obj_info);
58                if (r < 0)
59                        SC_FUNC_RETURN(card->ctx, 1, r);
60        }
61        return SC_SUCCESS;
62}
63
64static const prdata* get_prkey_by_cert(p15data_items* items, const cdata* cert) {
65        const prdata* keys;
66        if(!items->private_keys)
67                return NULL;
68        for(keys = items->private_keys; keys->id; keys++) {
69                if(0 == strcmp(cert->id, keys->id))
70                        return keys;
71        }
72        return NULL;
73}
74
75static int add_private_key(sc_pkcs15_card_t *p15card, const prdata* key, int usage, int modulus_length) {
76        struct sc_pkcs15_prkey_info prkey_info;
77        struct sc_pkcs15_object     prkey_obj;
78
79        memset(&prkey_info, 0, sizeof(prkey_info));
80        memset(&prkey_obj,  0, sizeof(prkey_obj));
81       
82        sc_pkcs15_format_id(key->id, &prkey_info.id);
83       
84        prkey_info.native        = 1;
85        prkey_info.key_reference = key->ref;
86
87        if(!modulus_length) modulus_length = key->modulus_len;
88        prkey_info.modulus_length= modulus_length;
89       
90        sc_format_path(key->path, &prkey_info.path);
91       
92        strncpy(prkey_obj.label, key->label, SC_PKCS15_MAX_LABEL_SIZE - 1);
93       
94        prkey_obj.flags = key->obj_flags;
95       
96        /* Setup key usage */
97        if(!usage) usage = key->usage;
98        prkey_info.usage = usage;
99       
100        if (key->auth_id)
101                sc_pkcs15_format_id(key->auth_id, &prkey_obj.auth_id);
102       
103        return sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
104}
105
106static int add_public_key(sc_pkcs15_card_t *p15card, const pubdata *key, int usage, int modulus_length) {
107        struct sc_pkcs15_pubkey_info pubkey_info;
108        struct sc_pkcs15_object     pubkey_obj;
109
110        memset(&pubkey_info, 0, sizeof(pubkey_info));
111        memset(&pubkey_obj,  0, sizeof(pubkey_obj));
112
113        sc_pkcs15_format_id(key->id, &pubkey_info.id);
114        if(!usage) usage = key->usage;
115        pubkey_info.usage         = usage;
116        pubkey_info.native        = 1;
117        pubkey_info.key_reference = key->ref;
118        if(!modulus_length) modulus_length = key->modulus_len;
119        pubkey_info.modulus_length= modulus_length;
120        /* we really don't know how many bits or module length,
121         * we will assume 1024 for now
122         */
123        sc_format_path(key->path, &pubkey_info.path);
124
125        strncpy(pubkey_obj.label, key->label, SC_PKCS15_MAX_LABEL_SIZE - 1);
126
127        pubkey_obj.flags = key->obj_flags;
128
129        if (key->auth_id)
130                sc_pkcs15_format_id(key->auth_id, &pubkey_obj.auth_id);
131
132        return sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
133}
134
135/* int default_cert_handle(sc_pkcs15_card_t *p15card, p15data_items* items, cdata* cert, u8* data, size_t length) { */
136CERT_HANDLE_FUNCTION(default_cert_handle) {
137        /* Certificate data exists, parse it */
138        int r;
139        X509 *cert_data = NULL;
140        EVP_PKEY *pkey = NULL;
141        int certtype = 0;
142        int modulus_len = 0;
143        const prdata* key = get_prkey_by_cert(items, cert);
144        if(!key) {
145                sc_error(p15card->card->ctx, "Error: No key for this certificate");
146                return SC_ERROR_INTERNAL;
147        }
148
149        if(!d2i_X509(&cert_data, (const u8**)&data, length)) {
150                sc_error(p15card->card->ctx, "Error converting certificate");
151                return SC_ERROR_INTERNAL;
152        }
153
154        pkey = X509_get_pubkey(cert_data);
155       
156        if(pkey == NULL) {
157                sc_error(p15card->card->ctx, "Error: no public key associated with the certificate");
158                r = SC_ERROR_INTERNAL;
159                goto err;
160        }
161        if(! EVP_PK_RSA & (certtype = X509_certificate_type(cert_data, pkey))) {
162                sc_error(p15card->card->ctx, "Error: certificate is not for an RSA key");
163                r = SC_ERROR_INTERNAL;
164                goto err;
165        }
166        if(pkey->pkey.rsa->n == NULL) {
167                sc_error(p15card->card->ctx, "Error: no modulus associated with the certificate");
168                r = SC_ERROR_INTERNAL;
169                goto err;
170        }
171       
172        modulus_len = 8 * BN_num_bytes(pkey->pkey.rsa->n); /* converting to bits */
173        /* printf("Key Size: %d bits\n\n", modulus_len); */
174        /* cached_cert->modulusLength = modulus_len; */
175       
176        if(key->label) {
177                int usage = 0;
178                if (certtype & EVP_PKT_SIGN) {
179                        usage |= SC_PKCS15_PRKEY_USAGE_SIGN;
180                        usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
181                }
182               
183                if (certtype & EVP_PKT_ENC) {
184                        usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT;
185                        usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT;
186                }
187                if (certtype & EVP_PKT_EXCH) {
188                        usage |= SC_PKCS15_PRKEY_USAGE_WRAP;
189                        usage |= SC_PKCS15_PRKEY_USAGE_UNWRAP;
190                }
191                r = add_private_key(p15card, key, usage, modulus_len);
192                if (r < 0)
193                        goto err;
194        }
195        r = SC_SUCCESS;
196err:
197        if(pkey) {
198                EVP_PKEY_free(pkey);
199                pkey = NULL;
200        }
201        if(cert_data) {
202                X509_free(cert_data);
203                cert_data = NULL;
204        }
205        SC_FUNC_RETURN(p15card->card->ctx, 1, r);
206}
207
208int sc_pkcs15emu_initialize_certificates(sc_pkcs15_card_t *p15card, p15data_items* items) {
209        /* set certs */
210        sc_card_t* card = p15card->card;
211        const cdata* certs = items->certs;
212        int onFailResume = items->cert_continue;
213        int i, r;
214        if(!certs) return SC_SUCCESS;
215        for (i = 0; certs[i].label; i++) {
216                struct sc_pkcs15_cert_info cert_info;
217                struct sc_pkcs15_object    cert_obj;
218               
219                memset(&cert_info, 0, sizeof(cert_info));
220                memset(&cert_obj,  0, sizeof(cert_obj));
221               
222                r = SC_SUCCESS;
223
224                sc_pkcs15_format_id(certs[i].id, &cert_info.id);
225                cert_info.authority = certs[i].authority;
226                sc_format_path(certs[i].path, &cert_info.path);
227
228                strncpy(cert_obj.label, certs[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
229                cert_obj.flags = certs[i].obj_flags;
230               
231                if(items->cert_load) {
232                        u8* cert_buffer = NULL;
233                        size_t cert_length = 0;
234                        int should_free = 0;
235                        if(SC_SUCCESS != (r = sc_select_file(card, &cert_info.path, NULL))) {
236                                if(onFailResume)
237                                        continue;
238                                else
239                                        break;
240                        }
241                        if(SC_SUCCESS != (r = items->cert_load(card, &cert_buffer, &cert_length, &should_free))) {
242                                if(onFailResume)
243                                        continue;
244                                else
245                                        break;
246                        }
247                        /* Handle cert */
248                        /* If no cert handler, add.. if cert handler succeeds.. add */
249                        if(!items->cert_handle || SC_SUCCESS == (r = items->cert_handle(p15card, items, &certs[i], cert_buffer, cert_length))) {
250                                r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
251                        }
252                        if(should_free)
253                                free(cert_buffer);
254                        if(SC_SUCCESS != r) {
255                                if(onFailResume)
256                                        continue;
257                                else
258                                        break;
259                        }
260                } else { /* Automatically add */
261                        if(SC_SUCCESS != (r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info))) {
262                                if(onFailResume)
263                                        continue;
264                                else
265                                        break;
266                        }
267                }
268        }
269        return SC_SUCCESS;
270}
271
272int sc_pkcs15emu_initialize_pins(sc_pkcs15_card_t *p15card, p15data_items* items) {
273        /* set pins */
274        int i,r;
275        const pindata* pins = items->pins;
276        if(!pins) return SC_SUCCESS;
277        for (i = 0; pins[i].label; i++) {
278                struct sc_pkcs15_pin_info pin_info;
279                struct sc_pkcs15_object   pin_obj;
280
281                memset(&pin_info, 0, sizeof(pin_info));
282                memset(&pin_obj,  0, sizeof(pin_obj));
283
284                sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
285                pin_info.reference     = pins[i].ref;
286                pin_info.flags         = pins[i].flags;
287                pin_info.type          = pins[i].type;
288                pin_info.min_length    = pins[i].minlen;
289                pin_info.stored_length = pins[i].storedlen;
290                pin_info.max_length    = pins[i].maxlen;
291                pin_info.pad_char      = pins[i].pad_char;
292                sc_format_path(pins[i].path, &pin_info.path);
293                pin_info.tries_left    = -1;
294
295                strncpy(pin_obj.label, pins[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
296                pin_obj.flags = pins[i].obj_flags;
297
298                if(0 > (r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info)))
299                        SC_FUNC_RETURN(p15card->card->ctx, 1, r);
300        }
301        return SC_SUCCESS;
302}
303
304int sc_pkcs15emu_initialize_private_keys(sc_pkcs15_card_t *p15card, p15data_items* items) {
305        const prdata *prkeys = items->private_keys;
306        int i, r;
307        if(!prkeys) return SC_SUCCESS;
308        /* set private keys */
309        for (i = 0; prkeys[i].label; i++) {
310                r = add_private_key(p15card, &prkeys[i], 0, 0);
311                if (r < 0)
312                        SC_FUNC_RETURN(p15card->card->ctx, 1, r);
313        }
314        return SC_SUCCESS;
315}
316
317int sc_pkcs15emu_initialize_public_keys(sc_pkcs15_card_t *p15card, p15data_items *items) {
318        const pubdata *keys = items->public_keys;
319        int i, r;
320        if(!keys) return SC_SUCCESS;
321        /* set public keys */
322        for (i = 0; keys[i].label; i++) {
323                r = add_public_key(p15card, &keys[i], 0, 0);
324                if (r < 0)
325                        SC_FUNC_RETURN(p15card->card->ctx, 1, r);
326        }
327        return SC_SUCCESS;
328
329}
330
331int sc_pkcs15emu_initialize_all(sc_pkcs15_card_t *p15card, p15data_items* items) {
332        int r;
333        if(SC_SUCCESS != (r = sc_pkcs15emu_initialize_objects(p15card, items)))
334                return r;
335        if(SC_SUCCESS != (r = sc_pkcs15emu_initialize_certificates(p15card, items)))
336                return r;
337        if(SC_SUCCESS != (r = sc_pkcs15emu_initialize_pins(p15card, items)))
338                return r;
339
340        if(items->forced_private && (SC_SUCCESS != (r = sc_pkcs15emu_initialize_private_keys(p15card, items))))
341                return r;
342        if(items->forced_public && (SC_SUCCESS != (r = sc_pkcs15emu_initialize_public_keys(p15card, items))))
343                return r;
344        return SC_SUCCESS;
345}
346
347#endif
Note: See TracBrowser for help on using the browser.