Ejemplo n.º 1
0
/*
 * Authenticate with the card. relogin should be set if we automatically
 * relogin after a fork.
 */
static
int pkcs11_login(PKCS11_SLOT * slot, int so, const char *pin, int relogin)
{
	PKCS11_SLOT_private *priv = PRIVSLOT(slot);
	PKCS11_CTX *ctx = priv->parent;
	int rv;

	if (relogin == 0) {
		CHECK_SLOT_FORK(slot);

		/* Calling PKCS11_login invalidates all cached
		 * keys we have */
		if (slot->token) {
			pkcs11_destroy_keys(slot->token, CKO_PRIVATE_KEY);
			pkcs11_destroy_keys(slot->token, CKO_PUBLIC_KEY);
		}
		if (priv->loggedIn) {
			/* already logged in, log out first */
			if (PKCS11_logout(slot))
				return -1;
		}
	}
	if (!priv->haveSession) {
		/* SO gets a r/w session by default,
		 * user gets a r/o session by default. */
		if (pkcs11_open_session(slot, so, relogin))
			return -1;
	}

	rv = CRYPTOKI_call(ctx,
		C_Login(priv->session, so ? CKU_SO : CKU_USER,
			(CK_UTF8CHAR *) pin, pin ? strlen(pin) : 0));
	if (rv && rv != CKR_USER_ALREADY_LOGGED_IN)  /* logged in -> OK   */
		CRYPTOKI_checkerr(PKCS11_F_PKCS11_LOGIN, rv);
	priv->loggedIn = 1;

	if (priv->prev_pin != pin) {
		if (priv->prev_pin) {
			OPENSSL_cleanse(priv->prev_pin, strlen(priv->prev_pin));
			OPENSSL_free(priv->prev_pin);
		}
		priv->prev_pin = BUF_strdup(pin);
	}
	priv->prev_so = so;
	return 0;
}
Ejemplo n.º 2
0
ByteArray SmartcardSlot::decrypt(std::string &keyId, std::string &pin, ByteArray &data)
		throw (SmartcardModuleException)
{
	int rc, found = 0, nret, keySize, j, errorCode;
	PKCS11_KEY *keys;
	ByteArray ret;
    unsigned int nKeys, i;
    std::string idTmp;
    char *bufferId;
    ERR_clear_error();
    if (pin.size() < 4 || pin.size() > 8)
    {
    	throw SmartcardModuleException(SmartcardModuleException::INVALID_PIN, "SmartcardSlot::decrypt", true);
    }
	rc = PKCS11_login(this->slot, 0, pin.c_str());
	if (rc != 0)
    {
    	errorCode = ERR_GET_REASON(ERR_get_error());
    	if (errorCode == SmartcardModuleException::BLOCKED_PIN)
    	{
    		throw SmartcardModuleException(SmartcardModuleException::BLOCKED_PIN, "SmartcardSlot::decrypt", true);
    	}
    	else if (errorCode == SmartcardModuleException::INVALID_PIN)
    	{
    		throw SmartcardModuleException(SmartcardModuleException::INVALID_PIN, "SmartcardSlot::decrypt", true);
    	}
    	else
    	{
    		throw SmartcardModuleException(SmartcardModuleException::UNKNOWN, "SmartcardSlot::decrypt", true);
    	}
    }
	rc = PKCS11_enumerate_keys(this->slot[0].token, &keys, &nKeys);
	if (rc != 0 || nKeys == 0)
	{
		PKCS11_logout(this->slot);
		throw SmartcardModuleException(SmartcardModuleException::ENUMERATING_PRIVATE_KEYS, "SmartcardSlot::decrypt", true);
	}
	found = -1;
	for (i=0;(i<nKeys)&&(found==-1);i++)
	{
		bufferId = (char *)calloc((keys[i].id_len * 2) + 1, sizeof(char));
		for (j=0;j<keys[i].id_len;j++)
		{
			sprintf(&(bufferId[j*2]), "%02X", keys[i].id[j]);
		}
		idTmp = bufferId;
		free(bufferId);
        if (keyId == idTmp)
        {
            found = i;
            keySize = PKCS11_get_key_size(&keys[i]);
        }
    }
	if (found < 0)
	{
		PKCS11_logout(this->slot);
		//TODO: apagar todas as chaves encontradas, não tem na libp11
		throw SmartcardModuleException(SmartcardModuleException::ID_NOT_FOUND, "SmartcardSlot::decrypt", true);
	}
	ret = ByteArray(keySize);
    nret = PKCS11_private_decrypt(data.size(), data.getDataPointer(), ret.getDataPointer(), &keys[found], RSA_PKCS1_PADDING);
    PKCS11_logout(this->slot);
    if (nret <= 0)
    {
		throw SmartcardModuleException(SmartcardModuleException::DECRYPTING_DATA, "SmartcardSlot::decrypt", true);
    }
    ret = ByteArray(ret.getDataPointer(), nret);
    return ret;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}