Ejemplo n.º 1
0
static int crypto_rsa_common(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* exponent, int exponent_size, BYTE* output)
{
	BN_CTX* ctx;
	int output_length = -1;
	BYTE* input_reverse;
	BYTE* modulus_reverse;
	BYTE* exponent_reverse;
	BIGNUM mod, exp, x, y;

	input_reverse = (BYTE*) malloc(2 * key_length + exponent_size);
	if (!input_reverse)
		return -1;
	modulus_reverse = input_reverse + key_length;
	exponent_reverse = modulus_reverse + key_length;

	memcpy(modulus_reverse, modulus, key_length);
	crypto_reverse(modulus_reverse, key_length);
	memcpy(exponent_reverse, exponent, exponent_size);
	crypto_reverse(exponent_reverse, exponent_size);
	memcpy(input_reverse, input, length);
	crypto_reverse(input_reverse, length);

	ctx = BN_CTX_new();
	if (!ctx)
		goto out_free_input_reverse;
	BN_init(&mod);
	BN_init(&exp);
	BN_init(&x);
	BN_init(&y);

	BN_bin2bn(modulus_reverse, key_length, &mod);
	BN_bin2bn(exponent_reverse, exponent_size, &exp);
	BN_bin2bn(input_reverse, length, &x);
	BN_mod_exp(&y, &x, &exp, &mod, ctx);

	output_length = BN_bn2bin(&y, output);
	crypto_reverse(output, output_length);

	if (output_length < (int) key_length)
		memset(output + output_length, 0, key_length - output_length);

	BN_free(&y);
	BN_clear_free(&x);
	BN_free(&exp);
	BN_free(&mod);
	BN_CTX_free(ctx);

out_free_input_reverse:
	free(input_reverse);

	return output_length;
}
Ejemplo n.º 2
0
static void crypto_rsa_common(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, int exponent_size, uint8* output)
{
	BN_CTX* ctx;
	int output_length;
	uint8* input_reverse;
	uint8* modulus_reverse;
	uint8* exponent_reverse;
	BIGNUM mod, exp, x, y;

	input_reverse = (uint8*) xmalloc(2 * key_length + exponent_size);
	modulus_reverse = input_reverse + key_length;
	exponent_reverse = modulus_reverse + key_length;

	memcpy(modulus_reverse, modulus, key_length);
	crypto_reverse(modulus_reverse, key_length);
	memcpy(exponent_reverse, exponent, exponent_size);
	crypto_reverse(exponent_reverse, exponent_size);
	memcpy(input_reverse, input, length);
	crypto_reverse(input_reverse, length);

	ctx = BN_CTX_new();
	BN_init(&mod);
	BN_init(&exp);
	BN_init(&x);
	BN_init(&y);

	BN_bin2bn(modulus_reverse, key_length, &mod);
	BN_bin2bn(exponent_reverse, exponent_size, &exp);
	BN_bin2bn(input_reverse, length, &x);
	BN_mod_exp(&y, &x, &exp, &mod, ctx);

	output_length = BN_bn2bin(&y, output);
	crypto_reverse(output, output_length);

	if (output_length < (int) key_length)
		memset(output + output_length, 0, key_length - output_length);

	BN_free(&y);
	BN_clear_free(&x);
	BN_free(&exp);
	BN_free(&mod);
	BN_CTX_free(ctx);
	xfree(input_reverse);
}
Ejemplo n.º 3
0
void crypto_rsa_encrypt(uint8* input, int length, uint32 key_length, uint8* modulus, uint8* exponent, uint8* output)
{
	BN_CTX* ctx;
	int output_length;
	uint8* input_reverse;
	uint8* modulus_reverse;
	uint8* exponent_reverse;
	BIGNUM mod, exp, x, y;

	input_reverse = (uint8*) xmalloc(2 * MODULUS_MAX_SIZE + EXPONENT_MAX_SIZE);
	modulus_reverse = input_reverse + MODULUS_MAX_SIZE;
	exponent_reverse = modulus_reverse + MODULUS_MAX_SIZE;

	memcpy(modulus_reverse, modulus, key_length);
	crypto_reverse(modulus_reverse, key_length);
	memcpy(exponent_reverse, exponent, EXPONENT_MAX_SIZE);
	crypto_reverse(exponent_reverse, EXPONENT_MAX_SIZE);
	memcpy(input_reverse, input, length);
	crypto_reverse(input_reverse, length);

	ctx = BN_CTX_new();
	BN_init(&mod);
	BN_init(&exp);
	BN_init(&x);
	BN_init(&y);

	BN_bin2bn(modulus_reverse, key_length, &mod);
	BN_bin2bn(exponent_reverse, EXPONENT_MAX_SIZE, &exp);
	BN_bin2bn(input_reverse, length, &x);
	BN_mod_exp(&y, &x, &exp, &mod, ctx);

	output_length = BN_bn2bin(&y, output);
	crypto_reverse(output, output_length);

	if (output_length < (int) key_length)
		memset(output + output_length, 0, key_length - output_length);

	BN_free(&y);
	BN_clear_free(&x);
	BN_free(&exp);
	BN_free(&mod);
	BN_CTX_free(ctx);
	xfree(input_reverse);
}
Ejemplo n.º 4
0
rdpRsaKey* key_new_from_content(const char* keycontent, const char* keyfile)
{
	BIO* bio = NULL;
	RSA* rsa = NULL;
	rdpRsaKey* key = NULL;
	const BIGNUM* rsa_e = NULL;
	const BIGNUM* rsa_n = NULL;
	const BIGNUM* rsa_d = NULL;
	key = (rdpRsaKey*) calloc(1, sizeof(rdpRsaKey));

	if (!key)
		return NULL;

	bio = BIO_new_mem_buf((void*)keycontent, strlen(keycontent));

	if (!bio)
		goto out_free;

	rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
	BIO_free(bio);

	if (!rsa)
	{
		WLog_ERR(TAG, "unable to load RSA key from %s: %s.", keyfile, strerror(errno));
		goto out_free;
	}

	switch (RSA_check_key(rsa))
	{
		case 0:
			WLog_ERR(TAG, "invalid RSA key in %s", keyfile);
			goto out_free_rsa;

		case 1:
			/* Valid key. */
			break;

		default:
			WLog_ERR(TAG, "unexpected error when checking RSA key from %s: %s.", keyfile, strerror(errno));
			goto out_free_rsa;
	}

	RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);

	if (BN_num_bytes(rsa_e) > 4)
	{
		WLog_ERR(TAG, "RSA public exponent too large in %s", keyfile);
		goto out_free_rsa;
	}

	key->ModulusLength = BN_num_bytes(rsa_n);
	key->Modulus = (BYTE*) malloc(key->ModulusLength);

	if (!key->Modulus)
		goto out_free_rsa;

	BN_bn2bin(rsa_n, key->Modulus);
	crypto_reverse(key->Modulus, key->ModulusLength);
	key->PrivateExponentLength = BN_num_bytes(rsa_d);
	key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength);

	if (!key->PrivateExponent)
		goto out_free_modulus;

	BN_bn2bin(rsa_d, key->PrivateExponent);
	crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);
	memset(key->exponent, 0, sizeof(key->exponent));
	BN_bn2bin(rsa_e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa_e));
	crypto_reverse(key->exponent, sizeof(key->exponent));
	RSA_free(rsa);
	return key;
out_free_modulus:
	free(key->Modulus);
out_free_rsa:
	RSA_free(rsa);
out_free:
	free(key);
	return NULL;
}
Ejemplo n.º 5
0
BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	wStream* s;
	int length;
	BYTE padding;
	UINT32 version;
	int modulus_length;
	int exponent_length;
	int error = 0;

	if (!cert || !info)
		return FALSE;

	memset(info, 0, sizeof(rdpCertInfo));
	s = Stream_New(cert->data, cert->length);

	if (!s)
		return FALSE;

	info->Modulus = 0;

	if (!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */
		goto error1;

	error++;

	if (!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */
		goto error1;

	error++;

	if (!ber_read_contextual_tag(s, 0, &length, TRUE))	/* Explicit Contextual Tag [0] */
		goto error1;

	error++;

	if (!ber_read_integer(s, &version)) /* version (INTEGER) */
		goto error1;

	error++;
	version++;

	/* serialNumber */
	if (!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */
		goto error1;

	error++;

	/* signature */
	if (!ber_read_sequence_tag(s, &length) ||
	    !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;

	error++;

	/* issuer */
	if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
		goto error1;

	error++;

	/* validity */
	if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Validity (SEQUENCE) */
		goto error1;

	error++;

	/* subject */
	if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */
		goto error1;

	error++;

	/* subjectPublicKeyInfo */
	if (!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */
		goto error1;

	error++;

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	if (!ber_read_sequence_tag(s, &length) ||
	    !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;

	error++;

	/* subjectPublicKeyInfo::subjectPublicKey */
	if (!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */
		goto error1;

	error++;

	/* RSAPublicKey (SEQUENCE) */
	if (!ber_read_sequence_tag(s, &length)) /* SEQUENCE */
		goto error1;

	error++;

	if (!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */
		goto error1;

	error++;

	/* skip zero padding, if any */
	do
	{
		if (Stream_GetRemainingLength(s) < 1)
			goto error1;

		Stream_Peek_UINT8(s, padding);

		if (padding == 0)
		{
			if (!Stream_SafeSeek(s, 1))
				goto error1;

			modulus_length--;
		}
	}
	while (padding == 0);

	error++;

	if (((int) Stream_GetRemainingLength(s)) < modulus_length)
		goto error1;

	info->ModulusLength = modulus_length;
	info->Modulus = (BYTE*) malloc(info->ModulusLength);

	if (!info->Modulus)
		goto error1;

	Stream_Read(s, info->Modulus, info->ModulusLength);
	error++;

	if (!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */
		goto error2;

	error++;

	if ((((int) Stream_GetRemainingLength(s)) < exponent_length) || (exponent_length > 4))
		goto error2;

	Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->Modulus, info->ModulusLength);
	crypto_reverse(info->exponent, 4);
	Stream_Free(s, FALSE);
	return TRUE;
error2:
	free(info->Modulus);
	info->Modulus = 0;
error1:
	WLog_ERR(TAG, "error reading when reading certificate: part=%s error=%d",
	         certificate_read_errors[error], error);
	Stream_Free(s, FALSE);
	return FALSE;
}
Ejemplo n.º 6
0
rdpRsaKey* key_new(const char* keyfile)
{
	BIO* bio = NULL;
	FILE* fp = NULL;
	RSA* rsa = NULL;
	int length;
	BYTE* buffer = NULL;
	rdpRsaKey* key = NULL;

	key = (rdpRsaKey*) calloc(1, sizeof(rdpRsaKey));

	if (!key)
		return NULL;

	fp = fopen(keyfile, "r+b");

	if (!fp)
	{
		WLog_ERR(TAG, "unable to open RSA key file %s: %s.", keyfile, strerror(errno));
		goto out_free;
	}

	fseek(fp, 0, SEEK_END);
	length = ftell(fp);
	fseek(fp, 0, SEEK_SET);

	buffer = (BYTE*) malloc(length);

	if (!buffer)
		goto out_free;

	fread((void*) buffer, length, 1, fp);
	fclose(fp);

	bio = BIO_new_mem_buf((void*) buffer, length);

	if (!bio)
		goto out_free;

	rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);

	BIO_free(bio);
	free(buffer);
	buffer = NULL;

	if (!rsa)
	{
		WLog_ERR(TAG, "unable to load RSA key from %s: %s.", keyfile, strerror(errno));
		goto out_free;
	}

	switch (RSA_check_key(rsa))
	{
		case 0:
			WLog_ERR(TAG, "invalid RSA key in %s", keyfile);
			goto out_free_rsa;

		case 1:
			/* Valid key. */
			break;

		default:
			WLog_ERR(TAG, "unexpected error when checking RSA key from %s: %s.", keyfile, strerror(errno));
			goto out_free_rsa;
	}

	if (BN_num_bytes(rsa->e) > 4)
	{
		WLog_ERR(TAG, "RSA public exponent too large in %s", keyfile);
		goto out_free_rsa;
	}

	key->ModulusLength = BN_num_bytes(rsa->n);
	key->Modulus = (BYTE*) malloc(key->ModulusLength);

	if (!key->Modulus)
		goto out_free_rsa;

	BN_bn2bin(rsa->n, key->Modulus);
	crypto_reverse(key->Modulus, key->ModulusLength);
	key->PrivateExponentLength = BN_num_bytes(rsa->d);
	key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength);

	if (!key->PrivateExponent)
		goto out_free_modulus;

	BN_bn2bin(rsa->d, key->PrivateExponent);
	crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);
	memset(key->exponent, 0, sizeof(key->exponent));
	BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
	crypto_reverse(key->exponent, sizeof(key->exponent));
	RSA_free(rsa);
	return key;
out_free_modulus:
	free(key->Modulus);
out_free_rsa:
	RSA_free(rsa);
out_free:
	if (fp)
		fclose(fp);
	if (buffer)
		free(buffer);
	free(key);
	return NULL;
}
Ejemplo n.º 7
0
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	STREAM* s;
	int length;
	uint8 padding;
	uint32 version;
	int modulus_length;
	int exponent_length;

	s = stream_new(0);
	s->p = s->data = cert->data;

	ber_read_sequence_tag(s, &length); /* Certificate (SEQUENCE) */

	ber_read_sequence_tag(s, &length); /* TBSCertificate (SEQUENCE) */

	/* Explicit Contextual Tag [0] */
	ber_read_contextual_tag(s, 0, &length, true);
	ber_read_integer(s, &version); /* version (INTEGER) */
	version++;

	/* serialNumber */
	ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */

	/* signature */
	ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
	stream_seek(s, length);

	/* issuer */
	ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
	stream_seek(s, length);

	/* validity */
	ber_read_sequence_tag(s, &length); /* Validity (SEQUENCE) */
	stream_seek(s, length);

	/* subject */
	ber_read_sequence_tag(s, &length); /* Name (SEQUENCE) */
	stream_seek(s, length);

	/* subjectPublicKeyInfo */
	ber_read_sequence_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	ber_read_sequence_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
	stream_seek(s, length);

	/* subjectPublicKeyInfo::subjectPublicKey */
	ber_read_bit_string(s, &length, &padding); /* BIT_STRING */

	/* RSAPublicKey (SEQUENCE) */
	ber_read_sequence_tag(s, &length); /* SEQUENCE */

	ber_read_integer_length(s, &modulus_length); /* modulus (INTEGER) */

	/* skip zero padding, if any */
	do
	{
		stream_peek_uint8(s, padding);

		if (padding == 0)
		{
			stream_seek(s, 1);
			modulus_length--;
		}
	}
	while (padding == 0);

	freerdp_blob_alloc(&info->modulus, modulus_length);
	stream_read(s, info->modulus.data, modulus_length);

	ber_read_integer_length(s, &exponent_length); /* publicExponent (INTEGER) */
	stream_read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->modulus.data, modulus_length);
	crypto_reverse(info->exponent, 4);
}
Ejemplo n.º 8
0
rdpRsaKey* key_new(const char* keyfile)
{
	FILE* fp;
	RSA* rsa;
	rdpRsaKey* key;

	key = (rdpRsaKey*) malloc(sizeof(rdpRsaKey));
	ZeroMemory(key, sizeof(rdpRsaKey));

	if (key == NULL)
		return NULL;

	fp = fopen(keyfile, "r");

	if (fp == NULL)
	{
		fprintf(stderr, "unable to load RSA key from %s: %s.", keyfile, strerror(errno));
		free(key) ;
		return NULL;
	}

	rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);

	if (rsa == NULL)
	{
		ERR_print_errors_fp(stdout);
		fclose(fp);
		free(key) ;
		return NULL;
	}

	fclose(fp);

	switch (RSA_check_key(rsa))
	{
		case 0:
			RSA_free(rsa);
			fprintf(stderr, "invalid RSA key in %s", keyfile);
			free(key) ;
			return NULL;

		case 1:
			/* Valid key. */
			break;

		default:
			ERR_print_errors_fp(stderr);
			RSA_free(rsa);
			free(key) ;
			return NULL;
	}

	if (BN_num_bytes(rsa->e) > 4)
	{
		RSA_free(rsa);
		fprintf(stderr, "RSA public exponent too large in %s", keyfile);
		free(key) ;
		return NULL;
	}

	key->ModulusLength = BN_num_bytes(rsa->n);
	key->Modulus = (BYTE*) malloc(key->ModulusLength);
	BN_bn2bin(rsa->n, key->Modulus);
	crypto_reverse(key->Modulus, key->ModulusLength);

	key->PrivateExponentLength = BN_num_bytes(rsa->d);
	key->PrivateExponent = (BYTE*) malloc(key->PrivateExponentLength);
	BN_bn2bin(rsa->d, key->PrivateExponent);
	crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);

	memset(key->exponent, 0, sizeof(key->exponent));
	BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
	crypto_reverse(key->exponent, sizeof(key->exponent));

	RSA_free(rsa);

	return key;
}
Ejemplo n.º 9
0
BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info)
{
	wStream* s;
	int length;
	BYTE padding;
	UINT32 version;
	int modulus_length;
	int exponent_length;
	int error = 0;

	s = stream_new(0);
	stream_attach(s, cert->data, cert->length);
	info->Modulus = 0;

	if(!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */
		goto error1;
	error++;

	if(!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */
		goto error1;
	error++;

	if(!ber_read_contextual_tag(s, 0, &length, TRUE))	/* Explicit Contextual Tag [0] */
		goto error1;
	error++;
	if(!ber_read_integer(s, &version)) /* version (INTEGER) */
		goto error1;
	error++;
	version++;

	/* serialNumber */
	if(!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */
		goto error1;
	error++;

	/* signature */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;
	error++;

	/* issuer */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */
		goto error1;
	error++;

	/* validity */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Validity (SEQUENCE) */
		goto error1;
	error++;

	/* subject */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* Name (SEQUENCE) */
		goto error1;
	error++;

	/* subjectPublicKeyInfo */
	if(!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */
		goto error1;
	error++;

	/* subjectPublicKeyInfo::AlgorithmIdentifier */
	if(!ber_read_sequence_tag(s, &length) || !stream_skip(s, length)) /* AlgorithmIdentifier (SEQUENCE) */
		goto error1;
	error++;

	/* subjectPublicKeyInfo::subjectPublicKey */
	if(!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */
		goto error1;
	error++;

	/* RSAPublicKey (SEQUENCE) */
	if(!ber_read_sequence_tag(s, &length)) /* SEQUENCE */
		goto error1;
	error++;

	if(!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */
		goto error1;
	error++;

	/* skip zero padding, if any */
	do
	{
		if(stream_get_left(s) < 1)
			goto error1;
		stream_peek_BYTE(s, padding);

		if (padding == 0)
		{
			if(!stream_skip(s, 1))
				goto error1;
			modulus_length--;
		}
	}
	while (padding == 0);
	error++;

	if(stream_get_left(s) < modulus_length)
		goto error1;
	info->ModulusLength = modulus_length;
	info->Modulus = (BYTE*) malloc(info->ModulusLength);
	stream_read(s, info->Modulus, info->ModulusLength);
	error++;

	if(!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */
		goto error2;
	error++;
	if(stream_get_left(s) < exponent_length || exponent_length > 4)
		goto error2;
	stream_read(s, &info->exponent[4 - exponent_length], exponent_length);
	crypto_reverse(info->Modulus, info->ModulusLength);
	crypto_reverse(info->exponent, 4);

	stream_detach(s);
	stream_free(s);
	return TRUE;

error2:
	free(info->Modulus);
	info->Modulus = 0;
error1:
	fprintf(stderr, "error reading when reading certificate: part=%s error=%d\n", certificate_read_errors[error], error);
	stream_detach(s);
	stream_free(s);
	return FALSE;
}
Ejemplo n.º 10
0
rdpKey* key_new(const char* keyfile)
{
	rdpKey* key;
	RSA *rsa;
	FILE *fp;

	key = (rdpKey*) xzalloc(sizeof(rdpKey));

	if (key == NULL)
		return NULL;

	fp = fopen(keyfile, "r");

	if (fp == NULL)
	{
		printf("unable to load RSA key from %s: %s.", keyfile, strerror(errno));
		return NULL;
	}

	rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);

	if (rsa == NULL)
	{
		ERR_print_errors_fp(stdout);
		fclose(fp);
		return NULL;
	}

	fclose(fp);

	switch (RSA_check_key(rsa))
	{
		case 0:
			RSA_free(rsa);
			printf("invalid RSA key in %s", keyfile);
			return NULL;

		case 1:
			/* Valid key. */
			break;

		default:
			ERR_print_errors_fp(stdout);
			RSA_free(rsa);
			return NULL;
	}

	if (BN_num_bytes(rsa->e) > 4)
	{
		RSA_free(rsa);
		printf("RSA public exponent too large in %s", keyfile);
		return NULL;
	}

	freerdp_blob_alloc(&key->modulus, BN_num_bytes(rsa->n));
	BN_bn2bin(rsa->n, key->modulus.data);
	crypto_reverse(key->modulus.data, key->modulus.length);
	freerdp_blob_alloc(&key->private_exponent, BN_num_bytes(rsa->d));
	BN_bn2bin(rsa->d, key->private_exponent.data);
	crypto_reverse(key->private_exponent.data, key->private_exponent.length);
	memset(key->exponent, 0, sizeof(key->exponent));
	BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
	crypto_reverse(key->exponent, sizeof(key->exponent));

	RSA_free(rsa);

	return key;
}
Ejemplo n.º 11
0
rdpRsaKey* key_new(const char* keyfile)
{
	FILE* fp;
	RSA* rsa;
	rdpRsaKey* key;

	key = (rdpRsaKey *)calloc(1, sizeof(rdpRsaKey));
	if (!key)
		return NULL;

	fp = fopen(keyfile, "r");
	if (fp == NULL)
	{
		fprintf(stderr, "%s: unable to open RSA key file %s: %s.", __FUNCTION__, keyfile, strerror(errno));
		goto out_free;
	}

	rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
	if (rsa == NULL)
	{
		fprintf(stderr, "%s: unable to load RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno));
		ERR_print_errors_fp(stderr);
		fclose(fp);
		goto out_free;
	}

	fclose(fp);

	switch (RSA_check_key(rsa))
	{
		case 0:
			fprintf(stderr, "%s: invalid RSA key in %s\n", __FUNCTION__, keyfile);
			goto out_free_rsa;

		case 1:
			/* Valid key. */
			break;

		default:
			fprintf(stderr, "%s: unexpected error when checking RSA key from %s: %s.", __FUNCTION__, keyfile, strerror(errno));
			ERR_print_errors_fp(stderr);
			goto out_free_rsa;
	}

	if (BN_num_bytes(rsa->e) > 4)
	{
		fprintf(stderr, "%s: RSA public exponent too large in %s\n", __FUNCTION__, keyfile);
		goto out_free_rsa;
	}

	key->ModulusLength = BN_num_bytes(rsa->n);
	key->Modulus = (BYTE *)malloc(key->ModulusLength);
	if (!key->Modulus)
		goto out_free_rsa;
	BN_bn2bin(rsa->n, key->Modulus);
	crypto_reverse(key->Modulus, key->ModulusLength);

	key->PrivateExponentLength = BN_num_bytes(rsa->d);
	key->PrivateExponent = (BYTE *)malloc(key->PrivateExponentLength);
	if (!key->PrivateExponent)
		goto out_free_modulus;
	BN_bn2bin(rsa->d, key->PrivateExponent);
	crypto_reverse(key->PrivateExponent, key->PrivateExponentLength);

	memset(key->exponent, 0, sizeof(key->exponent));
	BN_bn2bin(rsa->e, key->exponent + sizeof(key->exponent) - BN_num_bytes(rsa->e));
	crypto_reverse(key->exponent, sizeof(key->exponent));

	RSA_free(rsa);
	return key;

out_free_modulus:
	free(key->Modulus);
out_free_rsa:
	RSA_free(rsa);
out_free:
	free(key);
	return NULL;
}