예제 #1
0
파일: CryptRSA.cpp 프로젝트: BitMax/openitg
void RSAKey::Sign( const CString &data, CString &out ) const
{
	Bignum in;
	{
		unsigned char hash[20];
		SHA_Simple(data.data(), data.size(), hash);

		int nbytes = (bignum_bitcount(this->modulus) - 1) / 8;
		unsigned char *bytes = new unsigned char[nbytes];

		memset( bytes, 0xFF, nbytes );
		bytes[0] = 1;
		memcpy( bytes + nbytes - 20, hash, 20 );

		in = bignum_from_bytes(bytes, nbytes);
		delete [] bytes;
	}

	Bignum outnum = rsa_privkey_op(in, this);
	delete [] in;

	int siglen;
	unsigned char *bytes = bignum_to_bytes( outnum, &siglen );
	delete [] outnum;

	out = CString( (const char *) bytes, siglen );
	delete [] bytes;
}
예제 #2
0
파일: CryptRSA.cpp 프로젝트: BitMax/openitg
bool RSAKey::Decrypt( CString &buf ) const
{
	Bignum bn = bignum_from_buffer( (unsigned char *) buf.data(), buf.size() );
	if( bn == NULL )
		return false;

	Bignum decrypted_bn = Decrypt( bn );
	delete [] bn;

	int len;
	unsigned char *bytes = bignum_to_bytes( decrypted_bn, &len );
	buf = CString( (const char *) bytes, len );
	delete [] decrypted_bn;

	return true;
}
예제 #3
0
soter_status_t soter_engine_specific_to_rsa_priv_key(const soter_engine_specific_rsa_key_t *engine_key, soter_container_hdr_t *key, size_t* key_length)
{
	EVP_PKEY *pkey = (EVP_PKEY *)engine_key;
	RSA *rsa;
	soter_status_t res;
	int rsa_mod_size;
	size_t output_length;
	uint32_t *pub_exp;
	unsigned char *curr_bn = (unsigned char *)(key + 1);

	if (!key_length)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (EVP_PKEY_RSA != EVP_PKEY_id(pkey))
	{
		return SOTER_INVALID_PARAMETER;
	}

	rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
	if (NULL == rsa)
	{
		return SOTER_FAIL;
	}

	rsa_mod_size = RSA_size(rsa);
	if (!is_mod_size_supported(rsa_mod_size))
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	output_length = rsa_priv_key_size(rsa_mod_size);
	if ((!key) || (output_length > *key_length))
	{
		*key_length = output_length;
		res = SOTER_BUFFER_TOO_SMALL;
		goto err;
	}

	pub_exp = (uint32_t *)(curr_bn + ((rsa_mod_size * 4) + (rsa_mod_size / 2)));
	if (BN_is_word(rsa->e, RSA_F4))
	{
		*pub_exp = htonl(RSA_F4);
	}
	else if (BN_is_word(rsa->e, RSA_3))
	{
		*pub_exp = htonl(RSA_3);
	}
	else
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	/* Private exponent */
	res = bignum_to_bytes(rsa->d, curr_bn, rsa_mod_size);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size;

	/* p */
	res = bignum_to_bytes(rsa->p, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* q */
	res = bignum_to_bytes(rsa->q, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* dp */
	res = bignum_to_bytes(rsa->dmp1, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* dq */
	res = bignum_to_bytes(rsa->dmq1, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* qp */
	res = bignum_to_bytes(rsa->iqmp, curr_bn, rsa_mod_size / 2);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}
	curr_bn += rsa_mod_size / 2;

	/* modulus */
	res = bignum_to_bytes(rsa->n, curr_bn, rsa_mod_size);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}

	memcpy(key->tag, rsa_priv_key_tag(rsa_mod_size), SOTER_CONTAINER_TAG_LENGTH);
	key->size = htonl(output_length);
	soter_update_container_checksum(key);
	*key_length = output_length;
	res = SOTER_SUCCESS;

err:
	/* Free extra reference on RSA object provided by EVP_PKEY_get1_RSA */
	RSA_free(rsa);

//	if (SOTER_SUCCESS != res)
//	{
//		/* Zero output memory to avoid leaking private key information */
//		memset(key, 0, *key_length);
//	}

	return res;
}
예제 #4
0
soter_status_t soter_engine_specific_to_rsa_pub_key(const soter_engine_specific_rsa_key_t *engine_key, soter_container_hdr_t *key, size_t* key_length)
{
	EVP_PKEY *pkey = (EVP_PKEY *)engine_key;
	RSA *rsa;
	soter_status_t res;
	int rsa_mod_size;
	size_t output_length;
	uint32_t *pub_exp;

	if (!key_length)
	{
		return SOTER_INVALID_PARAMETER;
	}

	if (EVP_PKEY_RSA != EVP_PKEY_id(pkey))
	{
		return SOTER_INVALID_PARAMETER;
	}

	rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
	if (NULL == rsa)
	{
		return SOTER_FAIL;
	}

	rsa_mod_size = RSA_size(rsa);
	if (!is_mod_size_supported(rsa_mod_size))
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	output_length = rsa_pub_key_size(rsa_mod_size);
	if ((!key) || (output_length > *key_length))
	{
		*key_length = output_length;
		res = SOTER_BUFFER_TOO_SMALL;
		goto err;
	}

	pub_exp = (uint32_t *)((unsigned char *)(key + 1) + rsa_mod_size);
	if (BN_is_word(rsa->e, RSA_F4))
	{
		*pub_exp = htonl(RSA_F4);
	}
	else if (BN_is_word(rsa->e, RSA_3))
	{
		*pub_exp = htonl(RSA_3);
	}
	else
	{
		res = SOTER_INVALID_PARAMETER;
		goto err;
	}

	res = bignum_to_bytes(rsa->n, (unsigned char *)(key + 1), rsa_mod_size);
	if (SOTER_SUCCESS != res)
	{
		goto err;
	}

	memcpy(key->tag, rsa_pub_key_tag(rsa_mod_size), SOTER_CONTAINER_TAG_LENGTH);
	key->size = htonl(output_length);
	soter_update_container_checksum(key);
	*key_length = output_length;
	res = SOTER_SUCCESS;

err:
	/* Free extra reference on RSA object provided by EVP_PKEY_get1_RSA */
	RSA_free(rsa);

	return res;
}