1 /*
2  * SetOCS 4.4 specific operations for PKCS15 initialization
3  *
4  * Copyright (C) 2003, 2005 Zetes
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 "config.h"
22 
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 
27 #include "libopensc/opensc.h"
28 #include "libopensc/cardctl.h"
29 #include "libopensc/log.h"
30 #include "pkcs15-init.h"
31 #include "profile.h"
32 
33 #define SETCOS_MAX_PINS   7
34 
35 static unsigned char SETCOS_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01};
36 #define SETCOS_DEFAULT_PUBKEY_LEN       sizeof(SETCOS_DEFAULT_PUBKEY)
37 
38 static int setcos_create_pin_internal(sc_profile_t *, sc_pkcs15_card_t *,
39 	int, sc_pkcs15_auth_info_t *, const u8 *, size_t, const u8 *, size_t);
40 
41 
42 static int
setcos_puk_retries(sc_profile_t * profile,int pin_ref)43 setcos_puk_retries(sc_profile_t *profile, int pin_ref)
44 {
45 	sc_pkcs15_auth_info_t auth_info;
46 
47 	auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
48 	auth_info.attrs.pin.reference = 1; /* Default SO PIN ref. */
49 	sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info);
50 
51 	/* If pin_ref is the SO PIN, get the SO PUK info, otherwise the User PUK info */
52 	sc_profile_get_pin_info(profile,
53 		pin_ref == auth_info.attrs.pin.reference ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK,
54 		&auth_info);
55 
56 	if ((auth_info.tries_left < 0) || (auth_info.tries_left > 15))
57 		return 3; /* Little extra safety */
58 	return auth_info.tries_left;
59 }
60 
61 
62 /*
63  * Erase the card.
64  */
setcos_erase_card(sc_profile_t * profile,sc_pkcs15_card_t * p15card)65 static int setcos_erase_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
66 {
67 	sc_path_t path;
68 	int r;
69 
70 	/* Just delete the entire MF */
71 
72 	/* Select parent DF and verify PINs/key as necessary */
73 	r = sc_pkcs15init_authenticate(profile, p15card, profile->mf_info->file, SC_AC_OP_DELETE);
74 	if (r < 0)
75 		return r == SC_ERROR_FILE_NOT_FOUND ? 0 : r;
76 
77 	/* Empty path -> we have to to delete the current DF (= the MF) */
78 	memset(&path, 0, sizeof(sc_path_t));
79 	r = sc_delete_file(p15card->card, &path) ;
80 	if (r)
81 		return r;
82 
83 	sc_free_apps(p15card->card);
84 	return 0;
85 }
86 
87 
88 /*
89  * Create the MF and global pin file if they don't exist.
90  */
91 static int
setcos_init_card(sc_profile_t * profile,sc_pkcs15_card_t * p15card)92 setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
93 {
94 	struct sc_context *ctx = p15card->card->ctx;
95 	sc_file_t *mf = profile->mf_info->file;
96 	sc_file_t *pinfile;
97 	int r;
98 
99 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
100 
101 	/* Create the MF if it doesn't exist yet */
102 	r = sc_select_file(p15card->card, &mf->path, NULL);
103 	if (r == SC_ERROR_FILE_NOT_FOUND) {
104 		sc_log(ctx,  "MF doesn't exist, creating now");
105 
106 		/* Fix up the file's ACLs */
107 		r = sc_pkcs15init_fixup_file(profile, p15card, mf);
108 		LOG_TEST_RET(ctx, r, "MF fixup failed");
109 
110 		mf->status = SC_FILE_STATUS_CREATION;
111 		r = sc_create_file(p15card->card, mf);
112 		LOG_TEST_RET(ctx, r, "MF creation failed");
113 	}
114 	LOG_TEST_RET(ctx, r, "Cannot select MF");
115 
116 	/* Create the global pin file if it doesn't exist yet */
117 	r = sc_profile_get_file(profile, "pinfile", &pinfile);
118 	LOG_TEST_RET(ctx, r, "Cannot get 'pinfile' from profile");
119 
120 	r = sc_select_file(p15card->card, &pinfile->path, NULL);
121 	if (r == SC_ERROR_FILE_NOT_FOUND) {
122 		sc_log(ctx,  "Global pin file doesn't exist, creating now");
123 
124 		/* Fix up the file's ACLs */
125 		r = sc_pkcs15init_fixup_file(profile, p15card, pinfile);
126 		if (r < 0)
127 			sc_file_free(pinfile);
128 		LOG_TEST_RET(ctx, r, "Pinfile fixup failed");
129 
130 		/* Set life cycle state to SC_FILE_STATUS_CREATION,
131 		 * which means that all ACs are ignored. */
132 		pinfile->status = SC_FILE_STATUS_CREATION;
133 		r = sc_create_file(p15card->card, pinfile);
134 		if (r < 0)
135 			sc_file_free(pinfile);
136 		LOG_TEST_RET(ctx, r, "Pinfile creation failed");
137 	}
138 	sc_file_free(pinfile);
139 	LOG_TEST_RET(ctx, r, "Select pinfile failed");
140 
141 	LOG_FUNC_RETURN(ctx, r);
142 }
143 
144 /*
145  * Create a DF
146  */
147 static int
setcos_create_dir(sc_profile_t * profile,sc_pkcs15_card_t * p15card,sc_file_t * df)148 setcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
149 {
150 	struct sc_context *ctx = p15card->card->ctx;
151 	int r;
152 
153 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
154 
155         r = sc_pkcs15init_fixup_file(profile, p15card, df);
156 	LOG_TEST_RET(ctx, r, "SetCOS file ACL fixup failed");
157 
158 	r = sc_create_file(p15card->card, df);
159 	LOG_TEST_RET(ctx, r, "SetCOS create file failed");
160 
161 	LOG_FUNC_RETURN(ctx, r);
162 }
163 
164 
165 /*
166  * Select the PIN reference
167  */
168 static int
setcos_select_pin_reference(sc_profile_t * profile,sc_pkcs15_card_t * p15card,sc_pkcs15_auth_info_t * auth_info)169 setcos_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
170 	sc_pkcs15_auth_info_t *auth_info)
171 {
172 	sc_pkcs15_auth_info_t auth_info_prof;
173 
174 	auth_info_prof.attrs.pin.reference = 1; /* Default SO PIN ref. */
175 	auth_info_prof.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
176 	sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &auth_info_prof);
177 
178 	/* For the SO pin, we take the first available pin reference = 1 */
179 	if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
180 		auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference;
181 	/* sc_pkcs15init_create_pin() starts checking if -1 is an acceptable
182 	 * pin reference, which isn't for the SetCOS cards. And since the
183 	 * value 1 has been assigned to the SO pin, we'll jump to 2. */
184 	else if (auth_info->attrs.pin.reference <= 0)
185 		auth_info->attrs.pin.reference = auth_info_prof.attrs.pin.reference + 1;
186 
187 	return 0;
188 }
189 
190 /*
191  * Create a new PIN
192  */
193 static int
setcos_create_pin(sc_profile_t * profile,sc_pkcs15_card_t * p15card,sc_file_t * df,sc_pkcs15_object_t * pin_obj,const u8 * pin,size_t pin_len,const u8 * puk,size_t puk_len)194 setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
195 	sc_file_t *df,
196 	sc_pkcs15_object_t *pin_obj,
197 	const u8 *pin, size_t pin_len,
198 	const u8 *puk, size_t puk_len)
199 {
200 	struct sc_context *ctx = p15card->card->ctx;
201 	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
202 	sc_file_t *pinfile = NULL;
203 	int r, ignore_ac = 0;
204 
205 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
206 
207 	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
208 		return SC_ERROR_OBJECT_NOT_VALID;
209 
210         /* Create the global pin file if it doesn't exist yet */
211 	r = sc_profile_get_file(profile, "pinfile", &pinfile);
212 	LOG_TEST_RET(ctx, r, "No 'pinfile' template in profile");
213 
214 	r = sc_select_file(p15card->card, &pinfile->path, &pinfile);
215 	LOG_TEST_RET(ctx, r, "Cannot select 'pinfile'");
216 
217 	sc_log(ctx,  "pinfile->status:%X", pinfile->status);
218 	sc_log(ctx,  "create PIN with reference:%X, flags:%X, path:%s",
219 			auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path));
220 
221 	if (pinfile->status == SC_FILE_STATUS_CREATION)
222 		ignore_ac = 1;
223 
224 	r = setcos_create_pin_internal(profile, p15card, ignore_ac, auth_info,
225 			pin, pin_len, puk, puk_len);
226 
227 	/* If pinfile is in 'Creation' state and SOPIN has been created,
228 	 * change status of MF and 'pinfile' to 'Operational:Activated'
229 	 */
230 	if (ignore_ac && (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))   {
231 		sc_file_t *mf = profile->mf_info->file;
232 
233 		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
234 		LOG_TEST_RET(ctx, r, "Cannot set 'pinfile' into the activated state");
235 
236 		r = sc_select_file(p15card->card, &mf->path, NULL);
237 		LOG_TEST_RET(ctx, r, "Cannot select MF");
238 
239 		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
240 		LOG_TEST_RET(ctx, r, "Cannot set MF into the activated state");
241 	}
242 
243 	sc_file_free(pinfile);
244 
245 	LOG_FUNC_RETURN(ctx, r);
246 }
247 
248 /*
249  * Setup file struct & path: get correct template from the profile, construct full path
250  */
251 static int
setcos_new_file(sc_profile_t * profile,sc_card_t * card,unsigned int type,unsigned int num,sc_file_t ** out)252 setcos_new_file(sc_profile_t *profile, sc_card_t *card,
253 	unsigned int type,
254 	unsigned int num, /* number of objects of this type already on the card */
255 	sc_file_t **out)
256 {
257 	sc_file_t *file;
258 	sc_path_t *p;
259 	char name[64];
260 	const char *tag;
261 	int r;
262 
263 	if (type == SC_PKCS15_TYPE_PRKEY_RSA)
264 		tag = "private-key";
265 	else if (type  == SC_PKCS15_TYPE_PUBKEY_RSA)
266 		tag = "public-key";
267 	else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT)
268 		tag = "certificate";
269 	else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
270 		tag = "data";
271 	else {
272 		sc_log(card->ctx,  "Unsupported file type");
273 		return SC_ERROR_INVALID_ARGUMENTS;
274 	}
275 
276 	/* Get template from profile  */
277 	snprintf(name, sizeof(name), "template-%s", tag);
278 	if (sc_profile_get_file(profile, name, &file) < 0) {
279 		sc_log(card->ctx,  "Profile doesn't define %s", name);
280 		return SC_ERROR_NOT_SUPPORTED;
281 	}
282 
283 	/* Auto-increment FID for next object */
284 	file->id += num;
285 	p = &file->path;
286 	*p = profile->df_info->file->path;
287 	p->value[p->len++] = (u8) (file->id / 256);
288 	p->value[p->len++] = (u8) (file->id % 256);
289 
290 	/* Increment FID until there's no file with such path */
291 	r = sc_select_file(card, p, NULL);
292 	while(r == 0) {
293 		file->id++;
294 		p->value[p->len - 2] = (u8) (file->id / 256);
295 		p->value[p->len - 1] = (u8) (file->id % 256);
296 		r = sc_select_file(card, p, NULL);
297 	}
298 
299 	*out = file;
300 	return 0;
301 }
302 
303 static int
setcos_encode_private_key(sc_profile_t * profile,sc_card_t * card,struct sc_pkcs15_prkey_rsa * rsa,u8 * key,size_t * keysize,int key_ref)304 setcos_encode_private_key(sc_profile_t *profile, sc_card_t *card,
305 	struct sc_pkcs15_prkey_rsa *rsa,
306 	u8 *key, size_t *keysize, int key_ref)
307 {
308 	return 0;
309 }
310 
311 static int
setcos_encode_public_key(sc_profile_t * profile,sc_card_t * card,struct sc_pkcs15_prkey_rsa * rsa,u8 * key,size_t * keysize,int key_ref)312 setcos_encode_public_key(sc_profile_t *profile, sc_card_t *card,
313 	struct sc_pkcs15_prkey_rsa *rsa,
314 	u8 *key, size_t *keysize, int key_ref)
315 {
316 	return 0;
317 }
318 
319 
320 static int
setcos_create_key(sc_profile_t * profile,sc_pkcs15_card_t * p15card,struct sc_pkcs15_object * object)321 setcos_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
322 		struct sc_pkcs15_object *object)
323 {
324 	struct sc_context *ctx = p15card->card->ctx;
325 	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
326 	struct sc_file *file = NULL;
327 	int keybits = key_info->modulus_length, r;
328 
329 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
330 	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
331 		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported");
332 
333 	/* Parameter check */
334 	if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7))
335 		LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");
336 
337         sc_log(ctx,  "create private key ID:%s\n",  sc_pkcs15_print_id(&key_info->id));
338 
339 	/* Get the private key file */
340 	r = setcos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file);
341 	LOG_TEST_RET(ctx, r, "Cannot get new private key file");
342 
343 	/* Take enough room for a 1024 bit key */
344 	if (file->size < 512)
345 		file->size = 512;
346 
347 	/* Replace the path of instantiated key template by the path from the object data. */
348         memcpy(&file->path, &key_info->path, sizeof(file->path));
349         file->id = file->path.value[file->path.len - 2] * 0x100
350 		+ file->path.value[file->path.len - 1];
351 
352 	key_info->key_reference = file->path.value[file->path.len - 1] & 0xFF;
353 
354         sc_log(ctx,  "Path of private key file to create %s\n", sc_print_path(&file->path));
355 
356         r = sc_select_file(p15card->card, &file->path, NULL);
357         if (!r)   {
358 		r = sc_pkcs15init_delete_by_path(profile, p15card, &file->path);
359 		LOG_TEST_RET(ctx, r, "Failed to delete private key file");
360 	}
361         else if (r != SC_ERROR_FILE_NOT_FOUND)    {
362 		LOG_TEST_RET(ctx, r, "Select private key file error");
363 	}
364 
365 	/* Now create the key file */
366 	r = sc_pkcs15init_create_file(profile, p15card, file);
367 	LOG_TEST_RET(ctx, r, "Cannot create private key file");
368 
369 	sc_file_free(file);
370 	LOG_FUNC_RETURN(ctx, r);
371 }
372 
373 
374 /*
375  * Store a private key
376  */
377 static int
setcos_store_key(struct sc_profile * profile,struct sc_pkcs15_card * p15card,struct sc_pkcs15_object * object,struct sc_pkcs15_prkey * prkey)378 setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
379 		struct sc_pkcs15_object *object,
380 		struct sc_pkcs15_prkey *prkey)
381 {
382 	struct sc_context *ctx = p15card->card->ctx;
383 	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
384 	struct sc_cardctl_setcos_gen_store_key_info args;
385 	struct sc_file *file = NULL;
386 	int r, keybits = key_info->modulus_length;
387 
388 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
389 	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
390 		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");
391 
392 	/* Parameter check */
393 	if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7))
394 		LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");
395 
396 	sc_log(ctx,  "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id),
397 		       	sc_print_path(&key_info->path));
398 
399 	r = sc_select_file(p15card->card, &key_info->path, &file);
400 	LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed");
401 
402 	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
403 	LOG_TEST_RET(ctx, r, "No authorisation to store private key");
404 
405 	/* Fill in data structure */
406 	memset(&args, 0, sizeof(args));
407 	args.mod_len = keybits;
408 	args.op_type = OP_TYPE_STORE;
409 	args.pubexp_len = prkey->u.rsa.exponent.len * 8;
410 	args.pubexp = prkey->u.rsa.exponent.data;
411 	args.primep_len = prkey->u.rsa.p.len * 8;
412 	args.primep = prkey->u.rsa.p.data;
413 	args.primeq_len = prkey->u.rsa.q.len * 8;
414 	args.primeq = prkey->u.rsa.q.data;
415 
416 	/* Generate/store rsa key  */
417 	r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args);
418 	LOG_TEST_RET(ctx, r, "Card control 'GENERATE_STORE_KEY' failed");
419 
420 	sc_file_free(file);
421 
422 	LOG_FUNC_RETURN(ctx, r);
423 }
424 
425 
426 static int
setcos_generate_key(struct sc_profile * profile,struct sc_pkcs15_card * p15card,struct sc_pkcs15_object * object,struct sc_pkcs15_pubkey * pubkey)427 setcos_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
428 		struct sc_pkcs15_object *object,
429 		struct sc_pkcs15_pubkey *pubkey)
430 {
431 	struct sc_context *ctx = p15card->card->ctx;
432 	struct sc_cardctl_setcos_gen_store_key_info args;
433 	struct sc_cardctl_setcos_data_obj data_obj;
434 	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
435 	int r;
436 	size_t keybits = key_info->modulus_length;
437 	unsigned char raw_pubkey[256];
438 	struct sc_file *file = NULL;
439 
440 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
441 	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
442 		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported");
443 
444 	/* Parameter check */
445 	if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7))
446 		LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");
447 
448 	r = sc_select_file(p15card->card, &key_info->path, &file);
449 	LOG_TEST_RET(ctx, r, "Cannot store key: select key file failed");
450 
451 	/* Authenticate */
452 	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
453 	LOG_TEST_RET(ctx, r, "No authorisation to store private key");
454 
455 	/* Fill in data structure */
456 	memset(&args, 0, sizeof(args));
457 	args.mod_len = keybits;
458 	args.op_type = OP_TYPE_GENERATE;
459 	args.pubexp_len = SETCOS_DEFAULT_PUBKEY_LEN * 8;
460 	args.pubexp = SETCOS_DEFAULT_PUBKEY;
461 
462 	/* Generate/store rsa key  */
463 	r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args);
464 	LOG_TEST_RET(ctx, r, "Card control 'GENERATE_STORE_KEY' failed");
465 
466 	/* Key pair generation -> collect public key info */
467 	if (pubkey != NULL) {
468 		pubkey->algorithm		= SC_ALGORITHM_RSA;
469 		pubkey->u.rsa.modulus.len	= (keybits + 7) / 8;
470 		pubkey->u.rsa.modulus.data	= malloc(pubkey->u.rsa.modulus.len);
471 		pubkey->u.rsa.exponent.len	= SETCOS_DEFAULT_PUBKEY_LEN;
472 		pubkey->u.rsa.exponent.data	= malloc(SETCOS_DEFAULT_PUBKEY_LEN);
473 		memcpy(pubkey->u.rsa.exponent.data, SETCOS_DEFAULT_PUBKEY, SETCOS_DEFAULT_PUBKEY_LEN);
474 
475 		/* Get public key modulus */
476 		r = sc_select_file(p15card->card, &file->path, NULL);
477 		LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed");
478 
479 		data_obj.P1 = 0x01;
480 		data_obj.P2 = 0x01;
481 		data_obj.Data = raw_pubkey;
482 		data_obj.DataLen = sizeof(raw_pubkey);
483 
484 		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GETDATA, &data_obj);
485 		LOG_TEST_RET(ctx, r, "Cannot get key modulus: 'SETCOS_GETDATA' failed");
486 
487 		keybits = ((raw_pubkey[0] * 256) + raw_pubkey[1]);  /* modulus bit length */
488 		if (keybits != key_info->modulus_length)  {
489 			sc_log(ctx,
490 				 "key-size from card[%"SC_FORMAT_LEN_SIZE_T"u] does not match[%"SC_FORMAT_LEN_SIZE_T"u]\n",
491 				 keybits, key_info->modulus_length);
492 			LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Failed to generate key");
493 		}
494 		memcpy (pubkey->u.rsa.modulus.data, &raw_pubkey[2], pubkey->u.rsa.modulus.len);
495 	}
496 
497 	sc_file_free(file);
498 	return r;
499 }
500 
501 
502 /*
503  * Create a new PIN
504  */
505 static int
setcos_create_pin_internal(sc_profile_t * profile,sc_pkcs15_card_t * p15card,int ignore_ac,sc_pkcs15_auth_info_t * auth_info,const u8 * pin,size_t pin_len,const u8 * puk,size_t puk_len)506 setcos_create_pin_internal(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
507 	int ignore_ac, sc_pkcs15_auth_info_t *auth_info,
508 	const u8 *pin, size_t pin_len,
509 	const u8 *puk, size_t puk_len)
510 {
511 	struct sc_context *ctx = p15card->card->ctx;
512 	u8  data[32];
513 	int	r;
514 	struct sc_cardctl_setcos_data_obj data_obj;
515 	sc_file_t *pinfile = NULL;
516 
517 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
518 	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
519 		return SC_ERROR_OBJECT_NOT_VALID;
520 
521 	if (auth_info->attrs.pin.reference >= SETCOS_MAX_PINS)
522 		return SC_ERROR_INVALID_ARGUMENTS;
523 	if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
524 		return SC_ERROR_INVALID_PIN_LENGTH;
525 
526 	/* Verify required access rights if needed (i.e. if the
527 	 * pin file isn't in the CREATE life cycle state). */
528 	if (!ignore_ac) {
529 		r = sc_profile_get_file(profile, "pinfile", &pinfile);
530 		if (r >= 0)
531 			r = sc_pkcs15init_authenticate(profile, p15card, pinfile, SC_AC_OP_UPDATE);
532 		sc_file_free(pinfile);
533 		if (r < 0)
534 			return r;
535 	}
536 
537 	/* Make command to add a pin-record */
538 
539 	data_obj.P1 = 01;
540 	data_obj.P2 = 01;
541 
542 	/* setcos pin number */
543 	data[0] = auth_info->attrs.pin.reference;
544 
545 	memset(&data[1], auth_info->attrs.pin.pad_char, 16); /* padding */
546 	memcpy(&data[1], (u8 *)pin, pin_len);     /* copy pin*/
547 	memcpy(&data[9], (u8 *)puk, puk_len);     /* copy puk */
548 
549 	data[17] = auth_info->tries_left & 0x0F;
550 	data[18] = auth_info->tries_left & 0x0F;
551 	/* 0xF0: unlimited unblock tries */
552 	data[19] = 0xF0 | setcos_puk_retries(profile, auth_info->attrs.pin.reference);
553 
554 	/* Allow an unlimited number of signatures after a pin verification.
555 	 * If set to 1 or so, we would have a UserConsent PIN. */
556 	data[20] = 0x00;
557 
558 	if (auth_info->attrs.pin.type == 0)
559 		data[21] = 0x01; /* BCD */
560 	else
561 		data[21] = 0x00; /* ASCII */
562 	if ((auth_info->attrs.pin.flags & 0x010) == 0) /* test for initial pin */
563 		data[21] |= 0x80;
564 
565 	data[22]        = 0x00;			/* not used */
566 	data[23]        = 0x00;			/* not used */
567 
568 	data_obj.Data    = data;
569 	data_obj.DataLen = 24;
570 
571 	r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_PUTDATA, &data_obj);
572 
573 	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
574 }
575 
576 
577 static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = {
578 	setcos_erase_card,		/* erase_card */
579 	setcos_init_card,		/* init_card     */
580 	setcos_create_dir,		/* create_dir    */
581 	NULL,				/* create_domain */
582 	setcos_select_pin_reference,	/* select_pin_reference */
583 	setcos_create_pin,		/* create_pin */
584 	NULL, 				/* select_key_reference */
585 	setcos_create_key,		/* create_key */
586 	setcos_store_key,		/* store_key  */
587 	setcos_generate_key,		/* generate_key */
588 	setcos_encode_private_key, 	/* encode_private_key  */
589 	setcos_encode_public_key, 	/* encode_public_key */
590 	NULL,				/* finalize_card */
591 	NULL, 				/* delete_object */
592 	NULL,				/* emu_update_dir */
593 	NULL, 				/* emu_update_any_df */
594 	NULL, 				/* emu_update_tokeninfo */
595 	NULL, 				/* emu_write_info */
596 	NULL, 				/* emu_store_data */
597 	NULL				/* sanity_check */
598 };
599 
600 struct sc_pkcs15init_operations *
sc_pkcs15init_get_setcos_ops(void)601 sc_pkcs15init_get_setcos_ops(void)
602 {
603 	return &sc_pkcs15init_setcos_operations;
604 }
605