예제 #1
0
static int read_file(sc_pkcs15_card_t * p15card, u8 fid[2],
		u8 *efbin, size_t *len)
{
	sc_path_t path;
	int r;

	sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, 0);
	/* look this up with our AID */
	path.aid = sc_hsm_aid;
	/* we don't have a pre-known size of the file */
	path.count = -1;
	if (!p15card->opts.use_file_cache
			|| SC_SUCCESS != sc_pkcs15_read_cached_file(p15card, &path, &efbin, len)) {
		/* avoid re-selection of SC-HSM */
		path.aid.len = 0;
		r = sc_select_file(p15card->card, &path, NULL);
		LOG_TEST_RET(p15card->card->ctx, r, "Could not select EF");

		r = sc_read_binary(p15card->card, 0, efbin, *len, 0);
		LOG_TEST_RET(p15card->card->ctx, r, "Could not read EF");

		*len = r;

		if (p15card->opts.use_file_cache) {
			/* save this with our AID */
			path.aid = sc_hsm_aid;
			sc_pkcs15_cache_file(p15card, &path, efbin, *len);
		}
	}

	return SC_SUCCESS;
}
/* Loads certificates.
* Certificates are stored in a ZLib compressed form with
* a 4 byte header, so we extract, decompress and cache
* them.
*/
static int loadCertificate(sc_pkcs15_card_t * p15card, int i,
			   const char *certPath, const char *certLabel)
{
	unsigned char *compCert = NULL, *cert = NULL, size[2];
	unsigned long int compLen, len;
	sc_pkcs15_cert_info_t cert_info;
	sc_pkcs15_object_t cert_obj;
	sc_path_t cpath;
	sc_card_t *card = p15card->card;
	sc_pkcs15_id_t id;
	int r;

	memset(&cert_info, 0, sizeof(cert_info));
	memset(&cert_obj, 0, sizeof(cert_obj));

	sc_format_path(certPath, &cpath);

	if (sc_select_file(card, &cpath, NULL) != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	sc_read_binary(card, 2, size, 2, 0);

	compLen = (size[0] << 8) + size[1];
	compCert =
	    (unsigned char *) malloc(compLen * sizeof(unsigned char));
	len = 4 * compLen;	/*Approximation of the uncompressed size */
	cert = (unsigned char *) malloc(len * sizeof(unsigned char));

	sc_read_binary(card, 4, compCert, compLen, 0);

	if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) {
		sc_error(p15card->card->ctx, "Zlib error: %d", r);
		return SC_ERROR_INTERNAL;
	}

	cpath.index = 0;
	cpath.count = len;

	sc_pkcs15_cache_file(p15card, &cpath, cert, len);

	id.len=1;
	id.value[0] = i + 1;

	cert_info.id = id;
	cert_info.path = cpath;
	cert_info.authority = (i == 2);

	strlcpy(cert_obj.label, certLabel, sizeof(cert_obj.label));
	cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;

	sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);

	return SC_SUCCESS;
}
예제 #3
0
static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_pkcs15_id_t id, auth_id;
	unsigned char serial_buf[13], *serial;
	int flags;
	int r;

#ifdef ENABLE_ZLIB
	int i = 0, j = 0;
	const char *certLabel[] = {
		"User Non-repudiation Certificate",	/* "User Non-repudiation Certificate" */
		"TSA Certificate",
		"CA Certificate"
	};	
	const char *certPath[] =
	    { "3F00300060006002", "3F00300060006003", "3F00300060006004" };
#endif

	const char *keyPath = "3F00300040000008";
	const char *pinDfName = "05040200";
	
	/* const int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; */
	const int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN
				| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
				| SC_PKCS15_PRKEY_USAGE_ENCRYPT
				| SC_PKCS15_PRKEY_USAGE_DECRYPT;
	    
	const char *authPIN = "Authentication PIN";
	/* const char *nonrepPIN = "Non-repudiation PIN"; */

	const char *authPRKEY = "Authentication Key";
	/* const char *nonrepPRKEY = "Non repudiation Key"; */
	
	p15card->opts.use_file_cache = 1;	

	/* Get Serial number */
	sc_format_path("3F0030000001", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	sc_read_binary(card, 0xC3, serial_buf, 12, 0);
	serial = serial_buf;

	/*
	 * The serial number is 8 characters long. Later versions of the
	 * card have the serial number at a different offset, after 4 more
	 * bytes.
	 */
	if (serial[0] != 'H') {
		if (serial[4] == 'H')
			serial = &serial_buf[4];
		else
			return SC_ERROR_WRONG_CARD;
	}
	serial[8] = '\0';

	/* Controllo che il serial number inizi per "H" */
	if( serial[0] != 'H' ) 
		return SC_ERROR_WRONG_CARD;
			
	set_string(&p15card->tokeninfo->label, "Actalis");
	set_string(&p15card->tokeninfo->manufacturer_id, "Actalis");
	set_string(&p15card->tokeninfo->serial_number, (char *)serial);

#ifdef ENABLE_ZLIB
	for (i = 0; i < 3; i++) {
		sc_path_t cpath;
		sc_format_path(certPath[i], &cpath);

		if (sc_select_file(card, &cpath, NULL) == SC_SUCCESS) {
			unsigned char *compCert = NULL, *cert = NULL, size[2];
			unsigned int compLen, len;

			sc_pkcs15_cert_info_t cert_info;
			sc_pkcs15_object_t cert_obj;
			memset(&cert_info, 0, sizeof(cert_info));
			memset(&cert_obj, 0, sizeof(cert_obj));

			sc_read_binary(card, 2, size, 2, 0);
			compLen = (size[0] << 8) + size[1];
			compCert = malloc(compLen * sizeof(unsigned char));
			len = 3 * compLen;	/*Approximation of the uncompressed size */
			cert = malloc(len * sizeof(unsigned char));

			sc_read_binary(card, 4, compCert, compLen, 0);

			if (uncompress(cert, (unsigned long int *) &len,
				compCert, compLen) != Z_OK)
				return SC_ERROR_INTERNAL;
			cpath.index = 0;
			cpath.count = len;

			sc_pkcs15_cache_file(p15card, &cpath, cert, len);
			id.value[0] = j + 1;
			id.len = 1;
			cert_info.id = id;
			cert_info.path = cpath;
			cert_info.authority = (j>0);

			strlcpy(cert_obj.label, certLabel[j], sizeof(cert_obj.label));

			j++;
			cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
			sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
		}
	}
#endif
	
	/* adding PINs & private keys */
	flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED |
	    SC_PKCS15_PIN_FLAG_NEEDS_PADDING;	
	
	sc_format_path(pinDfName, &path);
	path.type = SC_PATH_TYPE_DF_NAME;
	
	id.value[0] = 1;
	id.len = 1;
	sc_pkcs15emu_add_pin(p15card, &id,
			     authPIN, &path, 0x81,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     5, 8, flags, 3, 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);
	
	sc_format_path(keyPath, &path);
	id.value[0] = 1;
	id.len = 1;
	auth_id.value[0] = 1;
	auth_id.len = 1;
	sc_pkcs15emu_add_prkey(p15card, &id,
		       authPRKEY,
		       SC_PKCS15_TYPE_PRKEY_RSA,
		       1024, authprkey_usage,
		       &path, 0x08,
		       &auth_id,
		       SC_PKCS15_CO_FLAG_PRIVATE);
	
	/* return to MF */
	sc_format_path("3F00", &path);
	sc_select_file(card, &path, NULL);
	{
		/* save old signature funcs */
		set_security_env = card->ops->set_security_env;
		/* set new one             */
		card->ops->set_security_env  = set_sec_env;
		card->ops->compute_signature = do_sign;
	}
	
	return SC_SUCCESS;

}