Example #1
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;
}
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;
}
Example #3
0
static EVP_PKEY *pkcs11_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id,
		UI_METHOD * ui_method, void *callback_data, int isPrivate)
{
	PKCS11_SLOT *slot;
	PKCS11_SLOT *found_slot = NULL;
	PKCS11_TOKEN *tok, *match_tok = NULL;
	PKCS11_KEY *keys, *selected_key = NULL;
	PKCS11_CERT *certs;
	EVP_PKEY *pk;
	unsigned int cert_count, key_count, n, m;
	unsigned char key_id[MAX_VALUE_LEN / 2];
	size_t key_id_len = sizeof(key_id);
	char *key_label = NULL;
	int slot_nr = -1;
	char tmp_pin[MAX_PIN_LENGTH];
	size_t tmp_pin_len = sizeof(tmp_pin);
	char flags[64];

	if (pkcs11_init_libp11(ctx)) /* Delayed libp11 initialization */
		return NULL;

	if (ctx->verbose)
		fprintf(stderr, "Loading %s key \"%s\"\n",
			(char *)(isPrivate ? "private" : "public"),
			s_slot_key_id);
	if (s_slot_key_id && *s_slot_key_id) {
		if (!strncmp(s_slot_key_id, "pkcs11:", 7)) {
			n = parse_pkcs11_uri(s_slot_key_id, &match_tok,
				key_id, &key_id_len,
				tmp_pin, &tmp_pin_len, &key_label);

			if (n && tmp_pin_len > 0 && tmp_pin[0] != 0) {
				destroy_pin(ctx);
				ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH * sizeof(char));
				if (ctx->pin != NULL) {
					memset(ctx->pin, 0, MAX_PIN_LENGTH * sizeof(char));
					memcpy(ctx->pin, tmp_pin, tmp_pin_len);
					ctx->pin_length = tmp_pin_len;
				}
			}

			if (!n) {
				fprintf(stderr,
					"The certificate ID is not a valid PKCS#11 URI\n"
					"The PKCS#11 URI format is defined by RFC7512\n");
				return NULL;
			}
		} else {
			n = parse_slot_id_string(s_slot_key_id, &slot_nr,
				key_id, &key_id_len, &key_label);

			if (!n) {
				fprintf(stderr,
					"The certificate ID is not a valid PKCS#11 URI\n"
					"The PKCS#11 URI format is defined by RFC7512\n"
					"The legacy ENGINE_pkcs11 ID format is also "
					"still accepted for now\n");
				return NULL;
			}
		}
		if (ctx->verbose) {
			fprintf(stderr, "Looking in slot %d for key: ",
				slot_nr);
			if (key_label == NULL) {
				for (n = 0; n < key_id_len; n++)
					fprintf(stderr, "%02x", key_id[n]);
				fprintf(stderr, "\n");
			} else
				fprintf(stderr, "label: %s\n", key_label);
		}
	}

	for (n = 0; n < ctx->slot_count; n++) {
		slot = ctx->slot_list + n;
		flags[0] = '\0';
		if (slot->token) {
			if (!slot->token->initialized)
				strcat(flags, "uninitialized, ");
			else if (!slot->token->userPinSet)
				strcat(flags, "no pin, ");
			if (slot->token->loginRequired)
				strcat(flags, "login, ");
			if (slot->token->readOnly)
				strcat(flags, "ro, ");
		} else {
			strcpy(flags, "no token");
		}
		if ((m = strlen(flags)) != 0) {
			flags[m - 2] = '\0';
		}

		if (slot_nr != -1 &&
			slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) {
			found_slot = slot;
		}
		if (match_tok && slot->token &&
				(match_tok->label == NULL ||
					!strcmp(match_tok->label, slot->token->label)) &&
				(match_tok->manufacturer == NULL ||
					!strcmp(match_tok->manufacturer, slot->token->manufacturer)) &&
				(match_tok->serialnr == NULL ||
					!strcmp(match_tok->serialnr, slot->token->serialnr)) &&
				(match_tok->model == NULL ||
					!strcmp(match_tok->model, slot->token->model))) {
			found_slot = slot;
		}
		if (ctx->verbose) {
			fprintf(stderr, "[%lu] %-25.25s  %-16s",
				PKCS11_get_slotid_from_slot(slot),
				slot->description, flags);
			if (slot->token) {
				fprintf(stderr, "  (%s)",
					slot->token->label[0] ?
					slot->token->label : "no label");
			}
			fprintf(stderr, "\n");
		}
	}

	if (match_tok) {
		OPENSSL_free(match_tok->model);
		OPENSSL_free(match_tok->manufacturer);
		OPENSSL_free(match_tok->serialnr);
		OPENSSL_free(match_tok->label);
		OPENSSL_free(match_tok);
	}
	if (found_slot) {
		slot = found_slot;
	} else if (match_tok) {
		fprintf(stderr, "Specified object not found\n");
		return NULL;
	} else if (slot_nr == -1) {
		if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx,
				ctx->slot_list, ctx->slot_count))) {
			fprintf(stderr, "No tokens found\n");
			return NULL;
		}
	} else {
		fprintf(stderr, "Invalid slot number: %d\n", slot_nr);
		return NULL;
	}
	tok = slot->token;

	if (tok == NULL) {
		fprintf(stderr, "Found empty token\n");
		return NULL;
	}
	/* The following check is non-critical to ensure interoperability
	 * with some other (which ones?) PKCS#11 libraries */
	if (!tok->initialized)
		fprintf(stderr, "Found uninitialized token\n");
	if (isPrivate && !tok->userPinSet && !tok->readOnly) {
		fprintf(stderr, "Found slot without user PIN\n");
		return NULL;
	}

	if (ctx->verbose) {
		fprintf(stderr, "Found slot:  %s\n", slot->description);
		fprintf(stderr, "Found token: %s\n", slot->token->label);
	}

	if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
		fprintf(stderr, "Unable to enumerate certificates\n");
		return NULL;
	}

	if (ctx->verbose) {
		fprintf(stderr, "Found %u certificate%s:\n", cert_count,
			(cert_count <= 1) ? "" : "s");
		for (n = 0; n < cert_count; n++) {
			PKCS11_CERT *c = certs + n;
			char *dn = NULL;

			fprintf(stderr, "  %2u    %s", n + 1, c->label);
			if (c->x509)
				dn = X509_NAME_oneline(X509_get_subject_name(c->x509), NULL, 0);
			if (dn) {
				fprintf(stderr, " (%s)", dn);
				OPENSSL_free(dn);
			}
			fprintf(stderr, "\n");
		}
	}

	if (isPrivate) {
		/* Perform login to the token if required */
		if (!pkcs11_login(ctx, slot, tok, ui_method, callback_data)) {
			fprintf(stderr, "login to token failed, returning NULL...\n");
			return NULL;
		}

		/* Make sure there is at least one private key on the token */
		if (PKCS11_enumerate_keys(tok, &keys, &key_count)) {
			fprintf(stderr, "Unable to enumerate private keys\n");
			return NULL;
		}
	} else {
		/* Make sure there is at least one public key on the token */
		if (PKCS11_enumerate_public_keys(tok, &keys, &key_count)) {
			fprintf(stderr, "Unable to enumerate public keys\n");
			return NULL;
		}
	}
	if (key_count == 0) {
		fprintf(stderr, "No %s keys found.\n",
			(char *)(isPrivate ? "private" : "public"));
		return NULL;
	}
	if (ctx->verbose)
		fprintf(stderr, "Found %u %s key%s:\n", key_count,
			(char *)(isPrivate ? "private" : "public"),
			(key_count == 1) ? "" : "s");

	if (s_slot_key_id && *s_slot_key_id &&
			(key_id_len != 0 || key_label != NULL)) {
		for (n = 0; n < key_count; n++) {
			PKCS11_KEY *k = keys + n;

			if (ctx->verbose) {
				fprintf(stderr, "  %2u %c%c %s\n", n + 1,
					k->isPrivate ? 'P' : ' ',
					k->needLogin ? 'L' : ' ', k->label);
			}
			if (key_label == NULL) {
				if (key_id_len != 0 && k->id_len == key_id_len
						&& memcmp(k->id, key_id, key_id_len) == 0) {
					selected_key = k;
				}
			} else {
				if (strcmp(k->label, key_label) == 0) {
					selected_key = k;
				}
			}
		}
	} else {
		selected_key = keys; /* Use the first key */
	}

	if (selected_key == NULL) {
		fprintf(stderr, "Key not found.\n");
		return NULL;
	}

	pk = isPrivate ?
		PKCS11_get_private_key(selected_key) :
		PKCS11_get_public_key(selected_key);
	if (key_label != NULL)
		OPENSSL_free(key_label);
	return pk;
}
Example #4
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;
}
Example #5
0
static X509 *pkcs11_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id)
{
	PKCS11_SLOT *slot;
	PKCS11_SLOT *found_slot = NULL;
	PKCS11_TOKEN *tok, *match_tok = NULL;
	PKCS11_CERT *certs, *selected_cert = NULL;
	X509 *x509;
	unsigned int cert_count, n, m;
	unsigned char cert_id[MAX_VALUE_LEN / 2];
	size_t cert_id_len = sizeof(cert_id);
	char *cert_label = NULL;
	char tmp_pin[MAX_PIN_LENGTH];
	size_t tmp_pin_len = sizeof(tmp_pin);
	int slot_nr = -1;
	char flags[64];

	if (pkcs11_init_libp11(ctx)) /* Delayed libp11 initialization */
		return NULL;

	if (s_slot_cert_id && *s_slot_cert_id) {
		if (!strncmp(s_slot_cert_id, "pkcs11:", 7)) {
			n = parse_pkcs11_uri(s_slot_cert_id, &match_tok,
				cert_id, &cert_id_len,
				tmp_pin, &tmp_pin_len, &cert_label);
			if (n && tmp_pin_len > 0 && tmp_pin[0] != 0) {
				destroy_pin(ctx);
				ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH * sizeof(char));
				if (ctx->pin != NULL) {
					memcpy(ctx->pin, tmp_pin, tmp_pin_len);
					ctx->pin_length = tmp_pin_len;
				}
				memset(ctx->pin, 0, MAX_PIN_LENGTH * sizeof(char));
			}

			if (!n) {
				fprintf(stderr,
					"The certificate ID is not a valid PKCS#11 URI\n"
					"The PKCS#11 URI format is defined by RFC7512\n");
				return NULL;
			}
		} else {
			n = parse_slot_id_string(s_slot_cert_id, &slot_nr,
				cert_id, &cert_id_len, &cert_label);

			if (!n) {
				fprintf(stderr,
					"The certificate ID is not a valid PKCS#11 URI\n"
					"The PKCS#11 URI format is defined by RFC7512\n"
					"The legacy ENGINE_pkcs11 ID format is also "
					"still accepted for now\n");
				return NULL;
			}
		}
		if (ctx->verbose) {
			fprintf(stderr, "Looking in slot %d for certificate: ",
				slot_nr);
			if (cert_label == NULL) {
				for (n = 0; n < cert_id_len; n++)
					fprintf(stderr, "%02x", cert_id[n]);
				fprintf(stderr, "\n");
			} else
				fprintf(stderr, "label: %s\n", cert_label);
		}
	}

	for (n = 0; n < ctx->slot_count; n++) {
		slot = ctx->slot_list + n;
		flags[0] = '\0';
		if (slot->token) {
			if (!slot->token->initialized)
				strcat(flags, "uninitialized, ");
			else if (!slot->token->userPinSet)
				strcat(flags, "no pin, ");
			if (slot->token->loginRequired)
				strcat(flags, "login, ");
			if (slot->token->readOnly)
				strcat(flags, "ro, ");
		} else {
			strcpy(flags, "no token");
		}
		if ((m = strlen(flags)) != 0) {
			flags[m - 2] = '\0';
		}

		if (slot_nr != -1 &&
			slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) {
			found_slot = slot;
		}
		if (match_tok && slot->token &&
				(match_tok->label == NULL ||
					!strcmp(match_tok->label, slot->token->label)) &&
				(match_tok->manufacturer == NULL ||
					!strcmp(match_tok->manufacturer, slot->token->manufacturer)) &&
				(match_tok->serialnr == NULL ||
					!strcmp(match_tok->serialnr, slot->token->serialnr)) &&
				(match_tok->model == NULL ||
					!strcmp(match_tok->model, slot->token->model))) {
			found_slot = slot;
		}
		if (ctx->verbose) {
			fprintf(stderr, "[%lu] %-25.25s  %-16s",
				PKCS11_get_slotid_from_slot(slot),
				slot->description, flags);
			if (slot->token) {
				fprintf(stderr, "  (%s)",
					slot->token->label[0] ?
					slot->token->label : "no label");
			}
			fprintf(stderr, "\n");
		}
	}

	if (match_tok) {
		OPENSSL_free(match_tok->model);
		OPENSSL_free(match_tok->manufacturer);
		OPENSSL_free(match_tok->serialnr);
		OPENSSL_free(match_tok->label);
		OPENSSL_free(match_tok);
	}
	if (found_slot) {
		slot = found_slot;
	} else if (match_tok) {
		fprintf(stderr, "Specified object not found\n");
		return NULL;
	} else if (slot_nr == -1) {
		if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx,
				ctx->slot_list, ctx->slot_count))) {
			fprintf(stderr, "No tokens found\n");
			return NULL;
		}
	} else {
		fprintf(stderr, "Invalid slot number: %d\n", slot_nr);
		return NULL;
	}
	tok = slot->token;

	if (tok == NULL) {
		fprintf(stderr, "Empty token found\n");
		return NULL;
	}

	if (ctx->verbose) {
		fprintf(stderr, "Found slot:  %s\n", slot->description);
		fprintf(stderr, "Found token: %s\n", slot->token->label);
	}

	/* In several tokens certificates are marked as private. We use the pin-value */
	if (tok->loginRequired && ctx->pin) {
		/* Now login in with the (possibly NULL) pin */
		if (PKCS11_login(slot, 0, ctx->pin)) {
			/* Login failed, so free the PIN if present */
			destroy_pin(ctx);
			fprintf(stderr, "Login failed\n");
			return NULL;
		}
	}

	if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) {
		fprintf(stderr, "Unable to enumerate certificates\n");
		return NULL;
	}

	if (ctx->verbose) {
		fprintf(stderr, "Found %u cert%s:\n", cert_count,
			(cert_count <= 1) ? "" : "s");
	}
	if ((s_slot_cert_id && *s_slot_cert_id) &&
			(cert_id_len != 0 || cert_label != NULL)) {
		for (n = 0; n < cert_count; n++) {
			PKCS11_CERT *k = certs + n;

			if (cert_label == NULL) {
				if (cert_id_len != 0 && k->id_len == cert_id_len &&
						memcmp(k->id, cert_id, cert_id_len) == 0)
					selected_cert = k;
			} else {
				if (strcmp(k->label, cert_label) == 0)
					selected_cert = k;
			}
		}
	} else {
		selected_cert = certs; /* Use the first certificate */
	}

	if (selected_cert == NULL) {
		fprintf(stderr, "Certificate not found.\n");
		return NULL;
	}

	x509 = X509_dup(selected_cert->x509);
	if (cert_label != NULL)
		OPENSSL_free(cert_label);
	return x509;
}
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;
}
Example #7
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;
}
Example #8
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;
}
Example #9
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;
}