Add API to load RSA key for Standard RDP Security in server mode.

This commit is contained in:
Pawel Jakub Dawidek 2012-01-25 16:45:21 +01:00
parent f5033b1a7c
commit ee9739f490
4 changed files with 91 additions and 0 deletions

View File

@ -17,6 +17,13 @@
* limitations under the License.
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include "certificate.h"
/**
@ -482,3 +489,71 @@ void certificate_free(rdpCertificate* certificate)
}
}
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;
}
void key_free(rdpKey* key)
{
if (key != NULL)
{
freerdp_blob_free(&key->modulus);
freerdp_blob_free(&key->private_exponent);
xfree(key);
}
}

View File

@ -42,6 +42,13 @@
#define BB_RSA_KEY_BLOB 6
#define BB_RSA_SIGNATURE_BLOB 8
struct rdp_key
{
rdpBlob modulus;
rdpBlob private_exponent;
uint8 exponent[4];
};
void certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info);
rdpX509CertChain* certificate_new_x509_certificate_chain(uint32 count);
@ -54,6 +61,9 @@ boolean certificate_read_server_certificate(rdpCertificate* certificate, uint8*
rdpCertificate* certificate_new(void);
void certificate_free(rdpCertificate* certificate);
rdpKey* key_new(const char *keyfile);
void key_free(rdpKey* key);
#ifdef WITH_DEBUG_CERTIFICATE
#define DEBUG_CERTIFICATE(fmt, ...) DEBUG_CLASS(CERTIFICATE, fmt, ## __VA_ARGS__)
#else

View File

@ -23,6 +23,10 @@ static boolean freerdp_peer_initialize(freerdp_peer* client)
{
client->context->rdp->settings->server_mode = true;
client->context->rdp->state = CONNECTION_STATE_INITIAL;
if (client->context->rdp->settings->rdp_key_file != NULL) {
client->context->rdp->settings->server_key =
key_new(client->context->rdp->settings->rdp_key_file);
}
return true;
}

View File

@ -198,6 +198,7 @@ void settings_free(rdpSettings* settings)
freerdp_blob_free(settings->server_certificate);
xfree(settings->server_random);
xfree(settings->server_certificate);
xfree(settings->rdp_key_file);
certificate_free(settings->server_cert);
xfree(settings->client_auto_reconnect_cookie);
xfree(settings->server_auto_reconnect_cookie);
@ -205,6 +206,7 @@ void settings_free(rdpSettings* settings)
xfree(settings->bitmapCacheV2CellInfo);
xfree(settings->glyphCache);
xfree(settings->fragCache);
key_free(settings->server_key);
xfree(settings);
}
}