Esempio n. 1
0
void digidoc::PKCS11Signer::unloadDriver()
{
    if(d->ctx == NULL)
        return;

    if(d->slots != NULL)
    {
        // Release all slots.
        PKCS11_release_all_slots(d->ctx, d->slots, d->numberOfSlots);
        d->slots = NULL;
    }

    // Release PKCS #11 context.
    PKCS11_CTX_unload(d->ctx);
    PKCS11_CTX_free(d->ctx);
    d->ctx = NULL;
}
Esempio n. 2
0
/* Finish engine operations initialized with pkcs11_init() */
int pkcs11_finish(ENGINE_CTX *ctx)
{
	if (ctx) {
		if (ctx->slot_list) {
			PKCS11_release_all_slots(ctx->pkcs11_ctx,
				ctx->slot_list, ctx->slot_count);
			ctx->slot_list = NULL;
			ctx->slot_count = 0;
		}
		if (ctx->pkcs11_ctx) {
			/* Modules cannot be unloaded in pkcs11_finish() nor
			 * pkcs11_destroy() because of a deadlock in PKCS#11
			 * modules that internally use OpenSSL engines.
			 * A memory leak is better than a deadlock... */
			/* PKCS11_CTX_unload(ctx->pkcs11_ctx); */
			PKCS11_CTX_free(ctx->pkcs11_ctx);
			ctx->pkcs11_ctx = NULL;
		}
	}
	return 1;
}
Esempio n. 3
0
int pkcs11_finish(ENGINE_CTX *ctx)
{
	if (ctx) {
		if (ctx->slot_list) {
			PKCS11_release_all_slots(ctx->pkcs11_ctx,
				ctx->slot_list, ctx->slot_count);
		}
		if (ctx->pkcs11_ctx) {
			PKCS11_CTX_unload(ctx->pkcs11_ctx);
			PKCS11_CTX_free(ctx->pkcs11_ctx);
		}
		destroy_pin(ctx);
		OPENSSL_free(ctx->module);
		OPENSSL_free(ctx->init_args);
#if OPENSSL_VERSION_NUMBER >= 0x10100004L
		CRYPTO_THREAD_lock_free(ctx->rwlock);
#else
		if (ctx->rwlock)
			CRYPTO_destroy_dynlockid(ctx->rwlock);
#endif
		OPENSSL_free(ctx);
	}
	return 1;
}
Esempio n. 4
0
static int
tap11_store_cert(
	const char *libp11,
	const char *pin,
	const char *certid,
	const char *certfile)
{
	int rc;
	unsigned int nslots;
	PKCS11_CTX *p11ctx;
	PKCS11_SLOT *slots, *slot;
	PKCS11_CERT *cert;
	X509 *x509;
	BIO *bio;

	p11ctx = PKCS11_CTX_new();

	/* load pkcs #11 module */
	rc = PKCS11_CTX_load(p11ctx,libp11);
	if (rc) {
		fprintf(stderr,"PKCS11_CTX_load\n");
		return -1;
	}

	/* get information on all slots */
	rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots);
	if (rc < 0) {
		fprintf(stderr,"PKCS11_enumerate_slots\n");
		return -1;
	}

	/* get first slot with a token */
	slot = PKCS11_find_token(p11ctx, slots, nslots);
	if (!slot || !slot->token) {
		fprintf(stderr,"PKCS11_find_token\n");
		return -1;
	}

	fprintf(stderr,"Slot manufacturer......: %s\n", slot->manufacturer);
	fprintf(stderr,"Slot description.......: %s\n", slot->description);
	fprintf(stderr,"Slot token label.......: %s\n", slot->token->label);
	fprintf(stderr,"Slot token manufacturer: %s\n", slot->token->manufacturer);
	fprintf(stderr,"Slot token model.......: %s\n", slot->token->model);
	fprintf(stderr,"Slot token serialnr....: %s\n", slot->token->serialnr);

	rc = PKCS11_open_session(slot, 1);
	if (rc != 0) {
		ERR_load_PKCS11_strings();
		fprintf(stderr,"PKCS11_open_session %s\n",
			ERR_reason_error_string(ERR_get_error()));
		return -1;
	}

	rc = PKCS11_login(slot, 0, pin);
	if (rc != 0) {
		ERR_load_PKCS11_strings();
		fprintf(stderr,"PKCS11_login %s\n",
			ERR_reason_error_string(ERR_get_error()));
		return -1;
	}

	/* load cert */
	if ((bio = BIO_new(BIO_s_file())) == NULL)
	{
		fprintf(stderr,"BIO_new\n");
		return -1;
	}
	if (BIO_read_filename(bio,certfile) <= 0) {
		fprintf(stderr,"BIO_read_filename\n");
		return -1;
	}
	x509 = PEM_read_bio_X509_AUX(bio,NULL, NULL, NULL);
	if (x509 == NULL) {
		fprintf(stderr,"PKCS11_enumerate_certs\n");
		return -1;
	}

	/* store cert */
	rc = PKCS11_store_certificate(slot->token,x509,
			(char*)certid,(unsigned char*)certid,strlen(certid),&cert);
	if (rc != 0) {
		ERR_load_PKCS11_strings();
		fprintf(stderr,"PKCS11_store_certificate %s rc:%d\n",
			ERR_reason_error_string(ERR_get_error()),rc);
		return -1;
	}

	X509_free(x509);
	BIO_free(bio);

	PKCS11_logout(slot);
	PKCS11_release_all_slots(p11ctx, slots, nslots);
	PKCS11_CTX_unload(p11ctx);
	PKCS11_CTX_free(p11ctx);

	fprintf(stderr,"\n\nstore cert succeed\n");

	return 0;
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
	PKCS11_CTX *ctx;
	PKCS11_SLOT *slots, *slot;
	PKCS11_CERT *certs;
	
	PKCS11_KEY *authkey;
	PKCS11_CERT *authcert;
	EVP_PKEY *pubkey = NULL;

	unsigned char *random = NULL, *signature = NULL;

	char password[20];
	int rc = 0, fd;
	unsigned int nslots, ncerts, siglen;

	if (argc < 2) {
		fprintf(stderr,
			"usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n",
			argv[0]);
		return 1;
	}

	do_fork();
	ctx = PKCS11_CTX_new();
	error_queue("PKCS11_CTX_new");

	/* load pkcs #11 module */
	do_fork();
	rc = PKCS11_CTX_load(ctx, argv[1]);
	error_queue("PKCS11_CTX_load");
	if (rc) {
		fprintf(stderr, "loading pkcs11 engine failed: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		rc = 1;
		goto nolib;
	}

	/* get information on all slots */
	do_fork();
	rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
	error_queue("PKCS11_enumerate_slots");
	if (rc < 0) {
		fprintf(stderr, "no slots available\n");
		rc = 2;
		goto noslots;
	}

	/* get first slot with a token */
	do_fork();
	slot = PKCS11_find_token(ctx, slots, nslots);
	error_queue("PKCS11_find_token");
	if (slot == NULL || slot->token == NULL) {
		fprintf(stderr, "no token available\n");
		rc = 3;
		goto notoken;
	}
	printf("Slot manufacturer......: %s\n", slot->manufacturer);
	printf("Slot description.......: %s\n", slot->description);
	printf("Slot token label.......: %s\n", slot->token->label);
	printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
	printf("Slot token model.......: %s\n", slot->token->model);
	printf("Slot token serialnr....: %s\n", slot->token->serialnr);

	if (!slot->token->loginRequired)
		goto loggedin;

	/* get password */
	if (argc > 2) {
		strcpy(password, argv[2]);
	} else {
		exit(1);
	}

loggedin:
	/* perform pkcs #11 login */
	do_fork();
	rc = PKCS11_login(slot, 0, password);
	error_queue("PKCS11_login");
	memset(password, 0, strlen(password));
	if (rc != 0) {
		fprintf(stderr, "PKCS11_login failed\n");
		goto failed;
	}

	/* get all certs */
	do_fork();
	rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts);
	error_queue("PKCS11_enumerate_certs");
	if (rc) {
		fprintf(stderr, "PKCS11_enumerate_certs failed\n");
		goto failed;
	}
	if (ncerts <= 0) {
		fprintf(stderr, "no certificates found\n");
		goto failed;
	}

	/* use the first cert */
	authcert=&certs[0];

	/* get random bytes */
	random = OPENSSL_malloc(RANDOM_SIZE);
	if (random == NULL)
		goto failed;

	fd = open(RANDOM_SOURCE, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n",
				strerror(errno));
		goto failed;
	}

	rc = read(fd, random, RANDOM_SIZE);
	if (rc < 0) {
		fprintf(stderr, "fatal: read from random source failed: %s\n",
			strerror(errno));
		close(fd);
		goto failed;
	}

	if (rc < RANDOM_SIZE) {
		fprintf(stderr, "fatal: read returned less than %d<%d bytes\n",
			rc, RANDOM_SIZE);
		close(fd);
		goto failed;
	}

	close(fd);

	do_fork();
	authkey = PKCS11_find_key(authcert);
	error_queue("PKCS11_find_key");
	if (authkey == NULL) {
		fprintf(stderr, "no key matching certificate available\n");
		goto failed;
	}

	/* ask for a sha1 hash of the random data, signed by the key */
	siglen = MAX_SIGSIZE;
	signature = OPENSSL_malloc(MAX_SIGSIZE);
	if (signature == NULL)
		goto failed;

	/* do the operations in child */
	do_fork();
	rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen,
			authkey);
	error_queue("PKCS11_sign");
	if (rc != 1) {
		fprintf(stderr, "fatal: pkcs11_sign failed\n");
		goto failed;
	}

	/* verify the signature */
	pubkey = X509_get_pubkey(authcert->x509);
	if (pubkey == NULL) {
		fprintf(stderr, "could not extract public key\n");
		goto failed;
	}

	/* now verify the result */
	rc = RSA_verify(NID_sha1, random, RANDOM_SIZE,
			signature, siglen, pubkey->pkey.rsa);
	if (rc != 1) {
		fprintf(stderr, "fatal: RSA_verify failed\n");
		goto failed;
	}

	if (pubkey != NULL)
		EVP_PKEY_free(pubkey);

	if (random != NULL)
		OPENSSL_free(random);
	if (signature != NULL)
		OPENSSL_free(signature);

	PKCS11_release_all_slots(ctx, slots, nslots);
	PKCS11_CTX_unload(ctx);
	PKCS11_CTX_free(ctx);

	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();

	printf("authentication successfull.\n");
	return 0;

failed:

notoken:
	PKCS11_release_all_slots(ctx, slots, nslots);

noslots:
	PKCS11_CTX_unload(ctx);

nolib:
	PKCS11_CTX_free(ctx);

	printf("authentication failed.\n");
	return 1;
}
Esempio n. 6
0
int main(int argc, char *argv[])
{
	PKCS11_CTX *ctx=NULL;
	PKCS11_SLOT *slots=NULL, *slot;
	PKCS11_KEY *keys;
	unsigned int nslots, nkeys;
	char password[20];
	int rc = 0;

	if (argc < 2) {
		fprintf(stderr,
			"usage: %s /usr/lib/opensc-pkcs11.so [PIN]\n",
			argv[0]);
		return 1;
	}

	ctx = PKCS11_CTX_new();
	error_queue("PKCS11_CTX_new");

	/* load pkcs #11 module */
	rc = PKCS11_CTX_load(ctx, argv[1]);
	error_queue("PKCS11_CTX_load");
	CHECK_ERR(rc < 0, "loading pkcs11 engine failed", 1);

	/* get information on all slots */
	rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
	error_queue("PKCS11_enumerate_slots");
	CHECK_ERR(rc < 0, "no slots available", 2);

	/* get first slot with a token */
	slot = PKCS11_find_token(ctx, slots, nslots);
	error_queue("PKCS11_find_token");
	CHECK_ERR(!slot || !slot->token, "no token available", 3);

	printf("Slot manufacturer......: %s\n", slot->manufacturer);
	printf("Slot description.......: %s\n", slot->description);
	printf("Slot token label.......: %s\n", slot->token->label);
	printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
	printf("Slot token model.......: %s\n", slot->token->model);
	printf("Slot token serialnr....: %s\n", slot->token->serialnr);

	/* get public keys */
	rc = PKCS11_enumerate_public_keys(slot->token, &keys, &nkeys);
	error_queue("PKCS11_enumerate_public_keys");
	CHECK_ERR(rc < 0, "PKCS11_enumerate_public_keys failed", 4);
	CHECK_ERR(nkeys == 0, "No public keys found", 5);
	list_keys("Public keys", keys, nkeys);

	if (slot->token->loginRequired && argc > 2) {
		strcpy(password, argv[2]);
		/* perform pkcs #11 login */
		rc = PKCS11_login(slot, 0, password);
		error_queue("PKCS11_login");
		memset(password, 0, strlen(password));
		CHECK_ERR(rc < 0, "PKCS11_login failed", 6);
	}

	/* get private keys */
	rc = PKCS11_enumerate_keys(slot->token, &keys, &nkeys);
	error_queue("PKCS11_enumerate_keys");
	CHECK_ERR(rc < 0, "PKCS11_enumerate_keys failed", 7);
	CHECK_ERR(nkeys == 0, "No private keys found", 8);
	list_keys("Private keys", keys, nkeys);

end:
	if (slots)
		PKCS11_release_all_slots(ctx, slots, nslots);
	if (ctx) {
		PKCS11_CTX_unload(ctx);
		PKCS11_CTX_free(ctx);
	}
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();

	if (rc)
		printf("Failed (error code %d).\n", rc);
	else
		printf("Success.\n");
	return rc;
}
Esempio n. 7
0
void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
{
	openconnect_close_https(vpninfo, 1);
	if (vpninfo->proto->udp_shutdown)
		vpninfo->proto->udp_shutdown(vpninfo);
	if (vpninfo->tncc_fd != -1)
		closesocket(vpninfo->tncc_fd);
	if (vpninfo->cmd_fd_write != -1) {
		closesocket(vpninfo->cmd_fd);
		closesocket(vpninfo->cmd_fd_write);
	}

#ifdef HAVE_ICONV
	if (vpninfo->ic_utf8_to_legacy != (iconv_t)-1)
		iconv_close(vpninfo->ic_utf8_to_legacy);

	if (vpninfo->ic_legacy_to_utf8 != (iconv_t)-1)
		iconv_close(vpninfo->ic_legacy_to_utf8);
#endif
#ifdef _WIN32
	if (vpninfo->cmd_event)
		CloseHandle(vpninfo->cmd_event);
	if (vpninfo->ssl_event)
		CloseHandle(vpninfo->ssl_event);
	if (vpninfo->dtls_event)
		CloseHandle(vpninfo->dtls_event);
#endif
	free(vpninfo->peer_addr);
	free(vpninfo->ip_info.gateway_addr);
	free_optlist(vpninfo->csd_env);
	free_optlist(vpninfo->script_env);
	free_optlist(vpninfo->cookies);
	free_optlist(vpninfo->cstp_options);
	free_optlist(vpninfo->dtls_options);
	free_split_routes(vpninfo);
	free(vpninfo->hostname);
	free(vpninfo->unique_hostname);
	free(vpninfo->urlpath);
	free(vpninfo->redirect_url);
	free(vpninfo->cookie);
	free(vpninfo->proxy_type);
	free(vpninfo->proxy);
	free(vpninfo->proxy_user);
	free(vpninfo->proxy_pass);
	free(vpninfo->vpnc_script);
	free(vpninfo->cafile);
	free(vpninfo->ifname);
	free(vpninfo->dtls_cipher);
#ifdef OPENCONNECT_GNUTLS
	gnutls_free(vpninfo->cstp_cipher); /* In OpenSSL this is const */
#ifdef HAVE_DTLS
	gnutls_free(vpninfo->gnutls_dtls_cipher);
#endif
#endif
	free(vpninfo->dtls_addr);

	if (vpninfo->csd_scriptname) {
		unlink(vpninfo->csd_scriptname);
		free(vpninfo->csd_scriptname);
	}
	free(vpninfo->mobile_platform_version);
	free(vpninfo->mobile_device_type);
	free(vpninfo->mobile_device_uniqueid);
	free(vpninfo->csd_token);
	free(vpninfo->csd_ticket);
	free(vpninfo->csd_stuburl);
	free(vpninfo->csd_starturl);
	free(vpninfo->csd_waiturl);
	free(vpninfo->csd_preurl);
	free(vpninfo->platname);
	if (vpninfo->opaque_srvdata)
		xmlFreeNode(vpninfo->opaque_srvdata);
	free(vpninfo->profile_url);
	free(vpninfo->profile_sha1);

	/* These are const in openconnect itself, but for consistency of
	   the library API we do take ownership of the strings we're given,
	   and thus we have to free them too. */
	if (vpninfo->cert != vpninfo->sslkey)
		free((void *)vpninfo->sslkey);
	free((void *)vpninfo->cert);
	if (vpninfo->peer_cert) {
#if defined(OPENCONNECT_OPENSSL)
		X509_free(vpninfo->peer_cert);
#elif defined(OPENCONNECT_GNUTLS)
		gnutls_x509_crt_deinit(vpninfo->peer_cert);
#endif
		vpninfo->peer_cert = NULL;
	}
	while (vpninfo->pin_cache) {
		struct pin_cache *cache = vpninfo->pin_cache;

		free(cache->token);
		memset(cache->pin, 0x5a, strlen(cache->pin));
		free(cache->pin);
		vpninfo->pin_cache = cache->next;
		free(cache);
	}

	free(vpninfo->peer_cert_sha1);
	free(vpninfo->peer_cert_sha256);
	free(vpninfo->localname);
	free(vpninfo->useragent);
	free(vpninfo->authgroup);
#ifdef HAVE_LIBSTOKEN
	if (vpninfo->stoken_pin)
		free(vpninfo->stoken_pin);
	if (vpninfo->stoken_ctx)
		stoken_destroy(vpninfo->stoken_ctx);
#endif
	if (vpninfo->oath_secret) {
#ifdef HAVE_LIBPSKC
		if (vpninfo->pskc)
			pskc_done(vpninfo->pskc);
		else
#endif /* HAVE_LIBPSKC */
		free(vpninfo->oath_secret);
	}
#ifdef HAVE_LIBPCSCLITE
	if (vpninfo->token_mode == OC_TOKEN_MODE_YUBIOATH) {
		SCardDisconnect(vpninfo->pcsc_card, SCARD_LEAVE_CARD);
		SCardReleaseContext(vpninfo->pcsc_ctx);
	}
	memset(vpninfo->yubikey_pwhash, 0, sizeof(vpninfo->yubikey_pwhash));
	free(vpninfo->yubikey_objname);
#endif
#ifdef HAVE_LIBP11
	if (vpninfo->pkcs11_ctx) {
		if (vpninfo->pkcs11_slot_list)
			PKCS11_release_all_slots(vpninfo->pkcs11_ctx,
						 vpninfo->pkcs11_slot_list,
						 vpninfo->pkcs11_slot_count);
		PKCS11_CTX_unload(vpninfo->pkcs11_ctx);
		PKCS11_CTX_free(vpninfo->pkcs11_ctx);
	}
	free(vpninfo->pkcs11_cert_id);
#endif
	/* These check strm->state so they are safe to call multiple times */
	inflateEnd(&vpninfo->inflate_strm);
	deflateEnd(&vpninfo->deflate_strm);

	free(vpninfo->deflate_pkt);
	free(vpninfo->tun_pkt);
	free(vpninfo->dtls_pkt);
	free(vpninfo->cstp_pkt);
	free(vpninfo);
}
Esempio n. 8
0
static int
tap11_change_pin(
	const char *p11lib,
	int is_so,
	const char *pin,
	const char *newpin)
{
	int rc = 0;
	unsigned int nslots;

	PKCS11_CTX *p11ctx;
	PKCS11_SLOT *slots, *slot;

	p11ctx = PKCS11_CTX_new();

	/* load pkcs #11 module */
	rc = PKCS11_CTX_load(p11ctx,p11lib);
	if (rc) {
		fprintf(stderr,"PKCS11_CTX_load\n");
		return -1;
	}

	/* get information on all slots */
	rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots);
	if (rc < 0) {
		fprintf(stderr,"PKCS11_enumerate_slots\n");
		return -1;
	}

	/* get first slot with a token */
	slot = PKCS11_find_token(p11ctx, slots, nslots);
	if (!slot || !slot->token) {
		fprintf(stderr,"PKCS11_find_token\n");
		return -1;
	}

	fprintf(stderr,"Slot manufacturer......: %s\n", slot->manufacturer);
	fprintf(stderr,"Slot description.......: %s\n", slot->description);
	fprintf(stderr,"Slot token label.......: %s\n", slot->token->label);
	fprintf(stderr,"Slot token manufacturer: %s\n", slot->token->manufacturer);
	fprintf(stderr,"Slot token model.......: %s\n", slot->token->model);
	fprintf(stderr,"Slot token serialnr....: %s\n", slot->token->serialnr);

	/* rw mode */
	rc = PKCS11_open_session(slot, 1);
	if (rc != 0) {
		ERR_load_PKCS11_strings();
		fprintf(stderr,"PKCS11_open_session %s\n",
			ERR_reason_error_string(ERR_get_error()));
		return -1;
	}

	rc = PKCS11_login(slot, is_so, pin);
	if (rc != 0) {
		ERR_load_PKCS11_strings();
		fprintf(stderr,"PKCS11_init_login %s\n",
			ERR_reason_error_string(ERR_get_error()));
		return -1;
	}

	rc = PKCS11_change_pin(slot,pin,newpin);
	if (rc != 0) {
		ERR_load_PKCS11_strings();
		fprintf(stderr,"PKCS11_change_pin %s\n",
			ERR_reason_error_string(ERR_get_error()));
		return -1;
	}

	PKCS11_logout(slot);
	PKCS11_release_all_slots(p11ctx, slots, nslots);
	PKCS11_CTX_unload(p11ctx);
	PKCS11_CTX_free(p11ctx);

	fprintf(stderr,"\n\npin change succeed\n");

	return 0;
}
Esempio n. 9
0
PKI_MEM_STACK *URL_get_data_pkcs11_url ( URL *url, ssize_t size ) {

#ifdef HAVE_P11
	// PKCS11_CTX   *ctx   = NULL;
	PKCS11_SLOT  *slots = NULL;
	PKCS11_TOKEN *tk    = NULL;

	char *libfile = NULL;
	int num = 0;
	int i = 0;

	char * search_label = NULL;
	char * search_id = NULL;
	char * search_slot = NULL;
	char * search_slotid = NULL;

	PKI_MEM *tmp_mem = NULL;
	PKI_MEM_STACK *sk = NULL;

	if( !url ) return (NULL);

	/*
	if((libfile = pkcs11_parse_url_libpath ( url )) == NULL ) {
		return( NULL );
	}
	*/

	/*
	slot = pkcs11_parse_url_slot ( url );
	id = pkcs11_parse_url_id ( url );
	*/

	if( ctx == NULL ) {
		if((ctx = PKCS11_CTX_new ()) == NULL ) {
			return(NULL);
		}

		PKI_log_debug("Loading %s Library", url->addr );
		if(( i = PKCS11_CTX_load(ctx, url->addr)) != 0 ) {
			PKI_log_err("Can not load library %s [err::%d]", url->addr, i);
			// ERR_print_errors_fp( stderr );
		}
	}

	if( PKCS11_enumerate_slots( ctx, &slots, &num ) == -1 ) {
		PKI_log_err ("Can not enumerate slots");
		goto err;
        };

	if(( sk = PKI_STACK_MEM_new()) == NULL ) {
		goto err;
	}

	search_slot   = pkcs11_parse_url_getval( url, "slot" );
	search_slotid = pkcs11_parse_url_getval( url, "slotid" );
	search_label  = pkcs11_parse_url_getval( url, "label" );
	search_id     = pkcs11_parse_url_getval( url, "id" );
	
	if( search_slot )
		PKI_log_debug("DEBUG::PKCS11::SEARCH::SLOT =>  %s\n", search_slot);
	if( search_slotid )
		PKI_log_debug("DEBUG::PKCS11::SEARCH::SLOTID =>  %s\n", search_slotid);
	if( search_label )
		PKI_log_debug("DEBUG::PKCS11::SEARCH::LABEL => %s\n", search_label);
	if( search_id )
		PKI_log_debug("DEBUG::PKCS11::SEARCH::ID =>    %s\n", search_id);

	for(i = 0; i < num; i++ ) {

		BIO *mem = NULL;
		BUF_MEM *mem_buf = NULL;

		PKCS11_CERT *certs = NULL;
		PKCS11_SLOT *p = NULL;
		PKCS11_CERT *x = NULL;

		PKCS11_KEY  *keyList = NULL;
		PKCS11_KEY  *key     = NULL;
		EVP_PKEY    *evp_pkey = NULL;

		int n = 0;
		int t = 0;
		int n_objs = 0;
		int p_ret = 0;
		
                p = &slots[i];

                if((!p) || ((tk = p->token) == NULL) ) {
			continue;
		}

		if( (search_slot) && ( strncmp_nocase( search_slot, 
				tk->label, strlen(search_slot) == 0) )) {
			continue;
		}

		if( (search_slotid) && ( atoi(search_slotid) != i )) {
			PKI_log_debug("PKCS11::SLOTID is %s (%d), curr is %d\n",
					search_slotid, atoi(search_slotid), i);
			continue;
		}

		if( strncmp_nocase( url->attrs, "cert", 4 ) == 0) {
			PKI_log_debug("PKCS11::CERT DATATYPE SELECTED!\n");
			if((mem = BIO_new(BIO_s_mem())) == NULL ) {
				goto err;
			}

			/* Get the list of certificates in the slot */
			p_ret = PKCS11_enumerate_certs( tk, &certs, &n_objs);

			for( n = 0; n < n_objs; n++ ) {

				/* Pointer to the current certificate */
				x = &certs[n];

				PKI_log_debug("PKCS11::CERT label=%s\n",
					x->label);
				PKI_log_debug("PKCS11::CERT id=");
				for( t = 0; t < x->id_len; t ++ ) {
					printf("%c", x->id[t] );
				} printf("\n");

				if( (search_label) &&
					(strncmp_nocase( search_label, x->label,
						strlen( search_label)) != 0 )){
					PKI_log_debug("PKCS11::LABEL does not"
						"match, SKIPPING!!!!\n");
					continue;
				}
 
				if( search_id ) {
					int stop = 0;

					for( t = 0; t < x->id_len; t ++ ) {
						if( search_id[t] != x->id[t] ) {
							stop = 1;
							break;
						}
					}

					if( stop == 1 ) { 
					printf("DEBUG::PKCS11::ID does not"
						"match, SKIPPING!!!!\n");
						continue;
					}
				}
 
				/* Write the cert in PEM format to memory */
				p_ret = PEM_write_bio_X509( mem, x->x509 );

				/* Get the pointer to the memory buffer */
				BIO_get_mem_ptr( mem, &mem_buf );

				/* Push a PKI_MEM buffer on the stack */
				tmp_mem = PKI_MEM_new_null();
				PKI_MEM_add ( tmp_mem, mem_buf->data, 
							mem_buf->length);
				PKI_STACK_push( sk, tmp_mem );
			}

			/* Free the temp memory buffer */
			if( mem ) BIO_free( mem );

		} else if (strncmp_nocase( url->attrs, "key", 3) == 0 ) {
			char *pin = NULL;

			PKI_log_debug("PKCS11::KEY DATATYPE SELECTED!\n");

			pin = pkcs11_parse_url_getval( url, "pin" );

			if ( (tk->loginRequired == 1) && (pin != NULL ) ) {
				p_ret = PKCS11_login ( p, 0, pin );
				PKI_log_debug("PKCS11::LOGIN Result %d\n",
					p_ret );
        		}

			if((mem = BIO_new(BIO_s_mem())) == NULL ) {
				goto err;
			}

		        p_ret = PKCS11_enumerate_keys ( tk, &keyList, &n_objs );

			for( n = 0; n < n_objs; n++ ) {
				key = &keyList[n];

				printf("DEBUG::PKCS11::KEY label=%s\n",
					key->label);
				printf("DEBUG::PKCS11::KEY id=");
				for( t = 0; t < key->id_len; t ++ ) {
					printf("%c", key->id[t] );
				} printf("\n");

				if( (search_label) &&
					(strncmp_nocase( search_label, x->label,
						strlen( search_label)) != 0 )){
					printf("DEBUG::PKCS11::LABEL does not"
						"match, SKIPPING!!!!\n");
					continue;
				}
 
				if( search_id ) {
					int stop = 0;

					for( t = 0; t < x->id_len; t ++ ) {
						if( search_id[t] != x->id[t] ) {
							stop = 1;
							break;
						}
					}

					if( stop == 1 ) { 
					printf("DEBUG::PKCS11::ID does not"
						"match, SKIPPING!!!!\n");
						continue;
					}
				}
 
				/* Get Private Key in OpenSSL format */
				evp_pkey = PKCS11_get_private_key( key );

				/* Write the cert in PEM format to memory */
				p_ret = PEM_write_bio_PUBKEY( mem, evp_pkey );

				/* Get the pointer to the memory buffer */
				BIO_get_mem_ptr( mem, &mem_buf );

				/* Push a PKI_MEM buffer on the stack */
				tmp_mem = PKI_MEM_new_null();
				PKI_MEM_add ( tmp_mem, mem_buf->data, 
							mem_buf->length);
				PKI_STACK_push( sk, tmp_mem );
			}

			if( mem ) BIO_free ( mem );

		} else {
			printf("DEBUG::PKCS11::OTHER DATATYPE SELECTED!\n");
		}
	}

err:
	if( slots ) PKCS11_release_all_slots( ctx, slots, num );

	/*
	if( ctx ) { 
		PKCS11_CTX_unload(ctx);
		PKCS11_CTX_free(ctx);
	}
	*/

	if( libfile ) PKI_Free (libfile);

	if( search_slot ) PKI_Free ( search_slot );
	if( search_slotid ) PKI_Free ( search_slotid );
	if( search_label ) PKI_Free ( search_label );
	if( search_id ) PKI_Free ( search_id );

	return ( sk );

#else
	return ( NULL );
#endif
}
Esempio n. 10
0
int main(int argc, char *argv[])
{
	PKCS11_CTX *ctx;
	PKCS11_SLOT *slots, *slot;
	unsigned char random[10];
	int rc = 0, i, len;
	unsigned int nslots;

	if (argc != 2) {
		fprintf(stderr, "usage: getrandom /usr/lib/opensc-pkcs11.so\n");
		return 1;
	}

	/* new context */
	ctx = PKCS11_CTX_new();

	/* load pkcs #11 module */
	rc = PKCS11_CTX_load(ctx, argv[1]);
	if (rc) {
		fprintf(stderr, "loading pkcs11 engine failed: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		rc = 1;
		goto nolib;
	}

	/* get information on all slots */
	rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
	if (rc < 0) {
		fprintf(stderr, "no slots available\n");
		rc = 2;
		goto noslots;
	}
	printf("%d slots available\n", nslots);

	/* get first slot with a token */
	slot = PKCS11_find_token(ctx, slots, nslots);
	if (!slot || !slot->token) {
		fprintf(stderr, "no token available\n");
		rc = 3;
		goto notoken;
	}
	printf("Slot manufacturer......: %s\n", slot->manufacturer);
	printf("Slot description.......: %s\n", slot->description);
	printf("Slot token label.......: %s\n", slot->token->label);
	printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
	printf("Slot token model.......: %s\n", slot->token->model);
	printf("Slot token serialnr....: %s\n", slot->token->serialnr);

	/* get 10 random bytes */
	len = sizeof(random);
	rc = PKCS11_generate_random(slot, random, len);
	if (rc < 0) {
		fprintf(stderr, "generate_random failed: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		rc = 4;
		goto norandom;
	}

	printf("\nRandom numbers generated by the token: ");
	for (i = 0; i < len; i++)
		printf("%02X ", random[i]);
	printf("\n");

	rc = 0;

      norandom:
      notoken:
	PKCS11_release_all_slots(ctx, slots, nslots);

      noslots:
	PKCS11_CTX_unload(ctx);

      nolib:
	PKCS11_CTX_free(ctx);
	return rc;
}
Esempio n. 11
0
/**
 * Finds all slots connected with the computer, if the slots have tokens, lists all
 * certificates found in token. If there are more that 1 certificate lets the user
 * application select (by calling the <code>selectSignCertificate</code> callback
 * function) the certificate used for signing.
 *
 * @return returns certificate used for signing.
 * @throws throws exception if failed to select the signing certificate. For example
 *         no cards found or card has no certificate.
 */
X509* digidoc::PKCS11Signer::getCert() throw(SignException)
{
    DEBUG("PKCS11Signer::getCert()");

    // If certificate is already selected return it.
    if(d->sign.certificate != NULL && d->sign.slot != NULL)
    {
        return d->sign.certificate->x509;
    }

    // Set selected state to 'no certificate selected'.
    d->sign.certificate = NULL;
    d->sign.slot = NULL;
    if(d->slots != NULL)
    {
        // Release all slots.
        PKCS11_release_all_slots(d->ctx, d->slots, d->numberOfSlots);
    }

    // Load all slots.
    if(PKCS11_enumerate_slots(d->ctx, &d->slots, &d->numberOfSlots) != 0)
    {
        THROW_SIGNEXCEPTION("Could not find any ID-Cards in any readers: %s", ERR_reason_error_string(ERR_get_error()));
    }

    // Iterate over all found slots, if the slot has a token, check if the token has any certificates.
    std::vector<PKCS11Signer::PKCS11Cert> certificates;
    std::vector<SignSlot> certSlotMapping;
    for(unsigned int i = 0; i < d->numberOfSlots; i++)
    {
        PKCS11_SLOT* slot = d->slots + i;

        if(slot->token != NULL)
        {
            PKCS11_CERT* certs = NULL;
            unsigned int numberOfCerts = 0;
            if(PKCS11_enumerate_certs(slot->token, &certs, &numberOfCerts))
            {
                // XXX: Should this throw an exception instead?
                WARN("Could not get certificates from token '%s'.", slot->token->label);
                continue;
            }

            // If no certificates on token skip the token.
            if(numberOfCerts <= 0)
            {
                continue;
            }

            // List all certificates found on this token.
            for(unsigned int j = 0; j < numberOfCerts; j++)
            {
                PKCS11_CERT* cert = certs + j;
                if(!d->checkCert(cert->x509))
                    break;
                SignSlot signSlot = { cert, slot };
                certSlotMapping.push_back( signSlot );
                certificates.push_back(d->createPKCS11Cert(slot, cert));
            }
        }
    }

    if(certificates.size() == 0)
    {
        THROW_SIGNEXCEPTION("No certificates found.");
    }

    // Let the application select the signing certificate.
    X509* selectedCert = selectSigningCertificate(certificates).cert;

    if(selectedCert == NULL)
    {
        THROW_SIGNEXCEPTION("No certificate selected.");
    }

    // Find the corresponding slot and PKCS11 certificate struct.
    for(std::vector<SignSlot>::const_iterator iter = certSlotMapping.begin(); iter != certSlotMapping.end(); iter++)
    {
        if(iter->certificate->x509 == selectedCert)
        {
            d->sign = *iter;
            break;
        }
    }

    if(d->sign.certificate == NULL || d->sign.slot == NULL)
    {
        THROW_SIGNEXCEPTION("Could not find slot for selected certificate.");
    }

    return d->sign.certificate->x509;
}
Esempio n. 12
0
int main (int argc, char * const argv[]) {
    // insert code here...
	//std::cout << "Hello World!\n";

	
	PKCS11_CTX *ctx;
	PKCS11_SLOT *slots, *slot;
	PKCS11_CERT *certs;
	
	PKCS11_KEY *authkey;
	PKCS11_CERT *authcert;
	EVP_PKEY *pubkey = NULL;
	
	
	unsigned char *random = NULL, *signature = NULL;
	
	char password[20];
	int rc = 0, fd;
	unsigned int nslots, ncerts, siglen;
	
	if (argc != 2) {
		printf("usage: auth /usr/lib/opensc-pkcs11.so\n");
		//return 1;
	}
	
	ctx = PKCS11_CTX_new();
	
	rc = PKCS11_CTX_load(ctx, "opensc-pkcs11.so");//argv[1]);
	if (rc) {
		printf("loading pkcs11 engine failed: %s\n",
				ERR_reason_error_string(ERR_get_error()));
		rc = 1;
		PKCS11_CTX_free(ctx);
		return 0;//goto nolib;
	}
	
	// get information on all slots 
	rc = PKCS11_enumerate_slots(ctx, &slots, &nslots);
	if (rc < 0) {
		printf("no slots available\n");
		rc = 2;
		PKCS11_CTX_unload(ctx);
		return 0;//goto noslots;
	}
	
	// get first slot with a token 
	slot = PKCS11_find_token(ctx, slots, nslots);

	if (!slot || !slot->token) {
		printf("no token available\n");
		rc = 3;
		
		PKCS11_release_all_slots(ctx, slots, nslots);
		return 0;//goto notoken;
	}
	
	
	printf("Slot manufacturer......: %s\n", slot->manufacturer);
	printf("Slot description.......: %s\n", slot->description);
	printf("Slot token label.......: %s\n", slot->token->label);
	printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
	printf("Slot token model.......: %s\n", slot->token->model);
	printf("Slot token serialnr....: %s\n", slot->token->serialnr);
	
	rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts);
	if (rc) {
		printf("PKCS11_enumerate_certs failed\n");
		return 0;//goto failed;
	}
	if (ncerts <= 0) {
		printf("no certificates found\n");
		return 0;//goto failed;
	}
	
	authcert=&certs[0];
	
	if (!slot->token->loginRequired)
		return 0;//goto loggedin;
	
	/*struct termios old, new;
	
	if (tcgetattr(0, &old) != 0)
		goto failed;
	
	new = old;
	new.c_lflag &= ~ECHO;
	if (tcsetattr(0, TCSAFLUSH, &new) != 0)
		goto failed;
	
	printf("Password for token %.32s: ", slot->token->label);
	fgets(password, sizeof(password), stdin);
	
	(void)tcsetattr(0, TCSAFLUSH, &old);
	
	rc = strlen(password);
	if (rc <= 0)
		goto failed;
	password[rc-1]=0;
	
	rc = PKCS11_login(slot, 0, password);
	memset(password, 0, strlen(password));
	if (rc != 0) {
		fprintf(stderr, "PKCS11_login failed\n");
		goto failed;
	}
	
loggedin:
	random = malloc(RANDOM_SIZE);
	if (!random)
		goto failed;
	
	fd = open(RANDOM_SOURCE, O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "fatal: cannot open RANDOM_SOURCE: %s\n",
				strerror(errno));
		goto failed;
	}
	
	rc = read(fd, random, RANDOM_SIZE);
	if (rc < 0) {
		fprintf(stderr, "fatal: read from random source failed: %s\n",
				strerror(errno));
		close(fd);
		goto failed;
	}
	
	if (rc < RANDOM_SIZE) {
		fprintf(stderr, "fatal: read returned less than %d<%d bytes\n",
				rc, RANDOM_SIZE);
		close(fd);
		goto failed;
	}
	
	close(fd);
	
	authkey = PKCS11_find_key(authcert);
	if (!authkey) {
		fprintf(stderr, "no key matching certificate available\n");
		goto failed;
	}
	
	siglen = MAX_SIGSIZE;
	signature = malloc(MAX_SIGSIZE);
	if (!signature)
		goto failed;
	
	rc = PKCS11_sign(NID_sha1, random, RANDOM_SIZE, signature, &siglen,
					 authkey);
	if (rc != 1) {
		fprintf(stderr, "fatal: pkcs11_sign failed\n");
		goto failed;
	}
	
	pubkey = X509_get_pubkey(authcert->x509);
	if (pubkey == NULL) {
		fprintf(stderr, "could not extract public key\n");
		goto failed;
	}
	
	rc = RSA_verify(NID_sha1, random, RANDOM_SIZE,
					signature, siglen, pubkey->pkey.rsa);
	if (rc != 1) {
		fprintf(stderr, "fatal: RSA_verify failed\n");
		goto failed;
	}
	
	if (pubkey != NULL)
		EVP_PKEY_free(pubkey);
	
	if (random != NULL)
		free(random);
	if (signature != NULL)
		free(signature);
	
	PKCS11_release_all_slots(ctx, slots, nslots);
	PKCS11_CTX_unload(ctx);
	PKCS11_CTX_free(ctx);
	
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();
	ERR_remove_state(0);
	
	printf("authentication successfull.\n");
	return 0;
	
	
failed:
	ERR_print_errors_fp(stderr);
notoken:
	PKCS11_release_all_slots(ctx, slots, nslots);
	
noslots:
	PKCS11_CTX_unload(ctx);
	
nolib:
	PKCS11_CTX_free(ctx);
	
	//-----
	
   */
    std::cout << "end\n";
	return 0;
}
Esempio n. 13
0
static Bool
LoadEnginePKCS11(SSL_CTX *ctx, ENGINE **e, const char *p11lib, const char *slotstr)
{
	char certid[PKCS11_BUF_SIZE];
	char certidbuf[PKCS11_BUF_SIZE];
	char pinbuf[PKCS11_BUF_SIZE];
	char *pin = NULL;
	EVP_PKEY *key = NULL;
	X509 *x509 = NULL;

	int rc = 0;
	int i;
	unsigned int nslots,ncerts;
	int nslot = 0;

	PKCS11_CTX *p11ctx;
	PKCS11_SLOT *slots, *slot;
	PKCS11_CERT *certs,*cert;

	pin = GetPasswordString(pinbuf, sizeof(pinbuf), PKCS11_ASKPIN_PROMPT);
	if (pin == NULL){
		Message("PIN input was canceled\n");
		return FALSE;
	}

	p11ctx = PKCS11_CTX_new();

	/* load pkcs #11 module */
	rc = PKCS11_CTX_load(p11ctx, p11lib);
	if (rc) {
		SSL_Error("loading pkcs11 engine failed: %s\n",
			ERR_reason_error_string(ERR_get_error()));
		return FALSE;
	}

	/* get information on all slots */
	rc = PKCS11_enumerate_slots(p11ctx, &slots, &nslots);
	if (rc < 0) {
		SSL_Error("no slots available\n");
		return FALSE;
	}

	/* get certificate and keyid by PKCS#11 */
	if (strcmp("",slotstr)){
		nslot = atoi(slotstr);
		if (nslot < nslots) {
			slot = (PKCS11_SLOT*)&slots[nslot];
			if (!slot || !slot->token) {
				SSL_Error("no token available\n");
				return FALSE;
			}
		} else {
			SSL_Error("no token available\n");
			return FALSE;
		}
	}
	else {
		/* get first slot with a token */
		slot = PKCS11_find_token(p11ctx, slots, nslots);
		if (!slot || !slot->token) {
			SSL_Error("no token available\n");
			return FALSE;
		}
		for(i=0;i<nslots;i++) {
			if (&slots[i] == slot) {
				nslot = i;
			}
		}
	}

	printf("Slot manufacturer......: %s\n", slot->manufacturer);
	printf("Slot description.......: %s\n", slot->description);
	printf("Slot token label.......: %s\n", slot->token->label);
	printf("Slot token manufacturer: %s\n", slot->token->manufacturer);
	printf("Slot token model.......: %s\n", slot->token->model);
	printf("Slot token serialnr....: %s\n", slot->token->serialnr);

	/* perform pkcs #11 login */
	rc = PKCS11_login(slot, 0, pin);
	if (rc != 0) {
		SSL_Error("PKCS11_login failed\n");
		return FALSE;
	}

	/* get all certs */
	rc = PKCS11_enumerate_certs(slot->token, &certs, &ncerts);
	if (rc) {
		SSL_Error("PKCS11_enumerate_certs failed\n");
		return FALSE;
	}
	if (ncerts <= 0) {
		SSL_Error("no certificates found\n");
		return FALSE;
	}

	/* use the first cert */
	cert=(PKCS11_CERT*)&certs[0];


	sprintf(certid,"slot_%d-id_",nslot);
	for(i=0;i<cert->id_len;i++) {
		sprintf(certidbuf,"%02x",(unsigned int)(cert->id[i]));
		strcat(certid,certidbuf);
	}
	printf("id:[%s] label:%s [%p]\n",certid,cert->label,cert->x509);
	x509 = X509_dup(cert->x509);

	PKCS11_logout(slot);
	PKCS11_release_all_slots(p11ctx, slots, nslots);
	PKCS11_CTX_unload(p11ctx);
	PKCS11_CTX_free(p11ctx);

	/* setup OpenSSL ENGINE */
	if (!(*e = InitEnginePKCS11(p11lib, pin))){
		return FALSE;
	} 
	if(!(key = ENGINE_load_private_key(*e, certid, NULL, NULL))) {
		SSL_Error(_d("ENGINE_load_private_key failure:\n %s\n"), GetSSLErrorString());
		return FALSE;
	}

	/* set key and cert to SSL_CTX */
	if (key){
		if (!SSL_CTX_use_certificate_with_check(ctx, x509)){
			SSL_Error(_d("SSL_CTX_use_certificate failure:\n %s"), GetSSLErrorString());
			return FALSE;
		}
		if (!SSL_CTX_use_PrivateKey(ctx, key)){
			SSL_Error(_d("SSL_CTX_use_PrivateKey failure:\n %s"), GetSSLErrorString());
			return FALSE;
		}
		if (!SSL_CTX_check_private_key(ctx)){
			SSL_Error(_d("SSL_CTX_check_private_key failure:\n %s\n"),
					GetSSLErrorString());
			return FALSE;
		}
	}
	memset(pin, 0, sizeof(pinbuf));
	return TRUE;
}