Пример #1
0
/* Following used for RSA */
int
PKCS11_sign(int type, const unsigned char *m, unsigned int m_len,
		unsigned char *sigret, unsigned int *siglen, PKCS11_KEY * key)
{
	int rv, ssl = ((type == NID_md5_sha1) ? 1 : 0);
	unsigned char *encoded = NULL;
	int sigsize;

	if (key == NULL)
		return 0;

	CHECK_KEY_FORK(key);

	sigsize = PKCS11_get_key_size(key);

	if (ssl) {
		if ((m_len != 36) /* SHA1 + MD5 */ ||
				((m_len + RSA_PKCS1_PADDING_SIZE) > (unsigned)sigsize)) {
			return 0; /* the size is wrong */
		}
	} else {
		ASN1_TYPE parameter = { V_ASN1_NULL, { NULL } };
 		ASN1_STRING digest = { m_len, V_ASN1_OCTET_STRING, (unsigned char *)m, 0 };
		X509_ALGOR algor = { NULL, &parameter };
		X509_SIG digest_info = { &algor, &digest };
		int size;
		/* Fetch the OID of the algorithm used */
		if ((algor.algorithm = OBJ_nid2obj(type)) &&
				(algor.algorithm) &&
				/* Get the size of the encoded DigestInfo */
				(size = i2d_X509_SIG(&digest_info, NULL)) &&
				/* Check that size is compatible with PKCS#11 padding */
				(size + RSA_PKCS1_PADDING_SIZE <= sigsize) &&
				(encoded = OPENSSL_malloc(sigsize))) {
			unsigned char *tmp = encoded;
			/* Actually do the encoding */
			i2d_X509_SIG(&digest_info,&tmp);
			m = encoded;
			m_len = size;
		} else {
			return 0;
		}
	}

	rv = PKCS11_private_encrypt(m_len, m, sigret, key, RSA_PKCS1_PADDING);

	if (rv <= 0)
		rv = 0;
	else {
		*siglen = rv;
		rv = 1;
	}

	if (encoded != NULL)  /* NULL on SSL case */
		OPENSSL_free(encoded);

	return rv;
}
Пример #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;
}
Пример #3
0
int
PKCS11_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
		PKCS11_KEY * key, int padding)
{
	PKCS11_KEY_private *priv;
	PKCS11_SLOT *slot;
	PKCS11_CTX *ctx;
	CK_SESSION_HANDLE session;
	CK_MECHANISM mechanism;
	int rv;
	int sigsize;
	CK_ULONG ck_sigsize;

	if (key == NULL)
		return -1;

	sigsize=PKCS11_get_key_size(key);
	ck_sigsize=sigsize;

	memset(&mechanism, 0, sizeof(mechanism));

	switch (padding) {

		case RSA_NO_PADDING:
			mechanism.mechanism = CKM_RSA_X_509;
			break;

		case RSA_PKCS1_PADDING:
			if ((flen + RSA_PKCS1_PADDING_SIZE) > sigsize) {
				return -1; /* the size is wrong */
			}
			mechanism.mechanism = CKM_RSA_PKCS;
			break;

		default:
			printf("pkcs11 engine: only RSA_NO_PADDING or RSA_PKCS1_PADDING allowed so far\n");
			return -1;
	}

	ctx = KEY2CTX(key);
	priv = PRIVKEY(key);
	slot = TOKEN2SLOT(priv->parent);

	CHECK_KEY_FORK(key);

	session = PRIVSLOT(slot)->session;

	pkcs11_w_lock(PRIVSLOT(slot)->lockid);
	/* API is somewhat fishy here. *siglen is 0 on entry (cleared
	 * by OpenSSL). The library assumes that the memory passed
	 * by the caller is always big enough */
	rv = CRYPTOKI_call(ctx, C_SignInit(session, &mechanism, priv->object)) ||
		CRYPTOKI_call(ctx,
			C_Sign(session, (CK_BYTE *) from, flen, to, &ck_sigsize));
	pkcs11_w_unlock(PRIVSLOT(slot)->lockid);

	if (rv) {
		PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv));
		return -1;
	}

	if ((unsigned)sigsize != ck_sigsize)
		return -1;

	return sigsize;
}