Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Philippe Auphelle 2012-01-23 11:06:52 +01:00
commit 0a454fe91d
21 changed files with 252 additions and 103 deletions

View File

@ -163,8 +163,16 @@ if(NOT WIN32)
add_subdirectory(channels) add_subdirectory(channels)
endif() endif()
add_subdirectory(client) option(WITH_CLIENT "Build client binaries" ON)
add_subdirectory(server) if(WITH_CLIENT)
add_subdirectory(client)
endif()
option(WITH_SERVER "Build server binaries" OFF)
if(WITH_SERVER)
add_subdirectory(server)
endif()
add_subdirectory(keymaps) add_subdirectory(keymaps)
# Source package # Source package

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(X11_INCLUDE_DIR NAMES Xlib.h find_path(X11_INCLUDE_DIR NAMES X11/Xlib.h
PATH_SUFFIXES X11 PATH_SUFFIXES X11
DOC "The X11 include directory" DOC "The X11 include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XKBFILE_INCLUDE_DIR NAMES XKBfile.h find_path(XKBFILE_INCLUDE_DIR NAMES X11/extensions/XKBfile.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The XKBFile include directory" DOC "The XKBFile include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XSHM_INCLUDE_DIR NAMES XShm.h find_path(XSHM_INCLUDE_DIR NAMES X11/extensions/XShm.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The XShm include directory" DOC "The XShm include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XTEST_INCLUDE_DIR NAMES XTest.h find_path(XTEST_INCLUDE_DIR NAMES X11/extensions/XTest.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The XTest include directory" DOC "The XTest include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XCURSOR_INCLUDE_DIR NAMES Xcursor.h find_path(XCURSOR_INCLUDE_DIR NAMES X11/Xcursor/Xcursor.h
PATH_SUFFIXES X11/Xcursor PATH_SUFFIXES X11/Xcursor
DOC "The Xcursor include directory" DOC "The Xcursor include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XDAMAGE_INCLUDE_DIR NAMES Xdamage.h find_path(XDAMAGE_INCLUDE_DIR NAMES X11/extensions/Xdamage.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The Xdamage include directory" DOC "The Xdamage include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XEXT_INCLUDE_DIR NAMES Xext.h find_path(XEXT_INCLUDE_DIR NAMES X11/extensions/Xext.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The Xext include directory" DOC "The Xext include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XFIXES_INCLUDE_DIR NAMES Xfixes.h find_path(XFIXES_INCLUDE_DIR NAMES X11/extensions/Xfixes.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The Xfixes include directory" DOC "The Xfixes include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XINERAMA_INCLUDE_DIR NAMES Xinerama.h find_path(XINERAMA_INCLUDE_DIR NAMES X11/extensions/Xinerama.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The Xinerama include directory" DOC "The Xinerama include directory"
) )

View File

@ -28,7 +28,7 @@
# limitations under the License. # limitations under the License.
#============================================================================= #=============================================================================
find_path(XV_INCLUDE_DIR NAMES Xv.h find_path(XV_INCLUDE_DIR NAMES X11/extensions/Xv.h
PATH_SUFFIXES X11/extensions PATH_SUFFIXES X11/extensions
DOC "The Xv include directory" DOC "The Xv include directory"
) )

View File

@ -256,9 +256,48 @@ static boolean certificate_process_server_public_key(rdpCertificate* certificate
return true; return true;
} }
static boolean certificate_process_server_public_signature(rdpCertificate* certificate, STREAM* s, uint32 length) static boolean certificate_process_server_public_signature(rdpCertificate* certificate, uint8* sigdata, int sigdatalen, STREAM* s, uint32 siglen)
{ {
stream_seek(s, length); uint8 md5hash[CRYPTO_MD5_DIGEST_LENGTH];
uint8 encsig[TSSK_KEY_LENGTH + 8];
uint8 sig[TSSK_KEY_LENGTH];
CryptoMd5 md5ctx;
int i, sum;
md5ctx = crypto_md5_init();
crypto_md5_update(md5ctx, sigdata, sigdatalen);
crypto_md5_final(md5ctx, md5hash);
stream_read(s, encsig, siglen);
/* Last 8 bytes shall be all zero. */
for (sum = 0, i = sizeof(encsig) - 8; i < sizeof(encsig); i++)
sum += encsig[i];
if (sum != 0) {
printf("certificate_process_server_public_signature: invalid signature\n");
//return false;
}
siglen -= 8;
crypto_rsa_public_decrypt(encsig, siglen, TSSK_KEY_LENGTH, tssk_modulus, tssk_exponent, sig);
/* Verify signature. */
if (memcmp(md5hash, sig, sizeof(md5hash)) != 0) {
printf("certificate_process_server_public_signature: invalid signature\n");
//return false;
}
/*
* Verify rest of decrypted data:
* The 17th byte is 0x00.
* The 18th through 62nd bytes are each 0xFF.
* The 63rd byte is 0x01.
*/
for (sum = 0, i = 17; i < 62; i++)
sum += sig[i];
if (sig[16] != 0x00 || sum != 0xFF * (62 - 17) || sig[62] != 0x01) {
printf("certificate_process_server_public_signature: invalid signature\n");
//return false;
}
return true; return true;
} }
@ -276,10 +315,14 @@ boolean certificate_read_server_proprietary_certificate(rdpCertificate* certific
uint32 wPublicKeyBlobLen; uint32 wPublicKeyBlobLen;
uint32 wSignatureBlobType; uint32 wSignatureBlobType;
uint32 wSignatureBlobLen; uint32 wSignatureBlobLen;
uint8* sigdata;
int sigdatalen;
/* -4, because we need to include dwVersion */
sigdata = stream_get_tail(s) - 4;
stream_read_uint32(s, dwSigAlgId); stream_read_uint32(s, dwSigAlgId);
stream_read_uint32(s, dwKeyAlgId); stream_read_uint32(s, dwKeyAlgId);
if (!(dwSigAlgId == 1 && dwKeyAlgId == 1)) if (!(dwSigAlgId == SIGNATURE_ALG_RSA && dwKeyAlgId == KEY_EXCHANGE_ALG_RSA))
{ {
printf("certificate_read_server_proprietary_certificate: parse error 1\n"); printf("certificate_read_server_proprietary_certificate: parse error 1\n");
return false; return false;
@ -296,6 +339,7 @@ boolean certificate_read_server_proprietary_certificate(rdpCertificate* certific
printf("certificate_read_server_proprietary_certificate: parse error 3\n"); printf("certificate_read_server_proprietary_certificate: parse error 3\n");
return false; return false;
} }
sigdatalen = stream_get_tail(s) - sigdata;
stream_read_uint16(s, wSignatureBlobType); stream_read_uint16(s, wSignatureBlobType);
if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB) if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
{ {
@ -303,7 +347,11 @@ boolean certificate_read_server_proprietary_certificate(rdpCertificate* certific
return false; return false;
} }
stream_read_uint16(s, wSignatureBlobLen); stream_read_uint16(s, wSignatureBlobLen);
if (!certificate_process_server_public_signature(certificate, s, wSignatureBlobLen)) if (wSignatureBlobLen != 72) {
printf("certificate_process_server_public_signature: invalid signature length (got %d, expected %d)\n", wSignatureBlobLen, 64);
return false;
}
if (!certificate_process_server_public_signature(certificate, sigdata, sigdatalen, s, wSignatureBlobLen))
{ {
printf("certificate_read_server_proprietary_certificate: parse error 5\n"); printf("certificate_read_server_proprietary_certificate: parse error 5\n");
return false; return false;

View File

@ -36,6 +36,9 @@
#define CERT_PERMANENTLY_ISSUED 0x00000000 #define CERT_PERMANENTLY_ISSUED 0x00000000
#define CERT_TEMPORARILY_ISSUED 0x80000000 #define CERT_TEMPORARILY_ISSUED 0x80000000
#define SIGNATURE_ALG_RSA 0x00000001
#define KEY_EXCHANGE_ALG_RSA 0x00000001
#define BB_RSA_KEY_BLOB 6 #define BB_RSA_KEY_BLOB 6
#define BB_RSA_SIGNATURE_BLOB 8 #define BB_RSA_SIGNATURE_BLOB 8

View File

@ -203,7 +203,7 @@ static boolean rdp_establish_keys(rdpRdp* rdp)
key_len = rdp->settings->server_cert->cert_info.modulus.length; key_len = rdp->settings->server_cert->cert_info.modulus.length;
mod = rdp->settings->server_cert->cert_info.modulus.data; mod = rdp->settings->server_cert->cert_info.modulus.data;
exp = rdp->settings->server_cert->cert_info.exponent; exp = rdp->settings->server_cert->cert_info.exponent;
crypto_rsa_encrypt(client_random, 32, key_len, mod, exp, crypt_client_random); crypto_rsa_public_encrypt(client_random, 32, key_len, mod, exp, crypt_client_random);
/* send crypt client random to server */ /* send crypt client random to server */
length = 7 + 8 + 4 + 4 + key_len + 8; length = 7 + 8 + 4 + 4 + key_len + 8;
@ -480,7 +480,7 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
ret = transport_accept_nla(rdp->transport); ret = transport_accept_nla(rdp->transport);
else if (rdp->nego->selected_protocol & PROTOCOL_TLS) else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
ret = transport_accept_tls(rdp->transport); ret = transport_accept_tls(rdp->transport);
else if (rdp->nego->selected_protocol & PROTOCOL_RDP) else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */
ret = transport_accept_rdp(rdp->transport); ret = transport_accept_rdp(rdp->transport);
if (!ret) if (!ret)

View File

@ -188,7 +188,35 @@ exit:
return status; return status;
} }
void crypto_rsa_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output) /*
* Terminal Services Signing Keys.
* Yes, Terminal Services Private Key is publically available.
*/
const uint8 tssk_modulus[] = {
0x3d, 0x3a, 0x5e, 0xbd, 0x72, 0x43, 0x3e, 0xc9,
0x4d, 0xbb, 0xc1, 0x1e, 0x4a, 0xba, 0x5f, 0xcb,
0x3e, 0x88, 0x20, 0x87, 0xef, 0xf5, 0xc1, 0xe2,
0xd7, 0xb7, 0x6b, 0x9a, 0xf2, 0x52, 0x45, 0x95,
0xce, 0x63, 0x65, 0x6b, 0x58, 0x3a, 0xfe, 0xef,
0x7c, 0xe7, 0xbf, 0xfe, 0x3d, 0xf6, 0x5c, 0x7d,
0x6c, 0x5e, 0x06, 0x09, 0x1a, 0xf5, 0x61, 0xbb,
0x20, 0x93, 0x09, 0x5f, 0x05, 0x6d, 0xea, 0x87
};
const uint8 tssk_privateExponent[] = {
0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55,
0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94,
0xcf, 0x92, 0xcc, 0x33, 0x99, 0xe8, 0x08, 0x60,
0x17, 0x9a, 0x12, 0x9f, 0x24, 0xdd, 0xb1, 0x24,
0x99, 0xc7, 0x3a, 0xb8, 0x0a, 0x7b, 0x0d, 0xdd,
0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3,
0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f
};
const uint8 tssk_exponent[] = {
0x5b, 0x7b, 0x88, 0xc0
};
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; BN_CTX* ctx;
int output_length; int output_length;
@ -197,14 +225,14 @@ void crypto_rsa_encrypt(const uint8* input, int length, uint32 key_length, const
uint8* exponent_reverse; uint8* exponent_reverse;
BIGNUM mod, exp, x, y; BIGNUM mod, exp, x, y;
input_reverse = (uint8*) xmalloc(2 * MODULUS_MAX_SIZE + EXPONENT_MAX_SIZE); input_reverse = (uint8*) xmalloc(2 * key_length + exponent_size);
modulus_reverse = input_reverse + MODULUS_MAX_SIZE; modulus_reverse = input_reverse + key_length;
exponent_reverse = modulus_reverse + MODULUS_MAX_SIZE; exponent_reverse = modulus_reverse + key_length;
memcpy(modulus_reverse, modulus, key_length); memcpy(modulus_reverse, modulus, key_length);
crypto_reverse(modulus_reverse, key_length); crypto_reverse(modulus_reverse, key_length);
memcpy(exponent_reverse, exponent, EXPONENT_MAX_SIZE); memcpy(exponent_reverse, exponent, exponent_size);
crypto_reverse(exponent_reverse, EXPONENT_MAX_SIZE); crypto_reverse(exponent_reverse, exponent_size);
memcpy(input_reverse, input, length); memcpy(input_reverse, input, length);
crypto_reverse(input_reverse, length); crypto_reverse(input_reverse, length);
@ -215,7 +243,7 @@ void crypto_rsa_encrypt(const uint8* input, int length, uint32 key_length, const
BN_init(&y); BN_init(&y);
BN_bin2bn(modulus_reverse, key_length, &mod); BN_bin2bn(modulus_reverse, key_length, &mod);
BN_bin2bn(exponent_reverse, EXPONENT_MAX_SIZE, &exp); BN_bin2bn(exponent_reverse, exponent_size, &exp);
BN_bin2bn(input_reverse, length, &x); BN_bin2bn(input_reverse, length, &x);
BN_mod_exp(&y, &x, &exp, &mod, ctx); BN_mod_exp(&y, &x, &exp, &mod, ctx);
@ -233,6 +261,48 @@ void crypto_rsa_encrypt(const uint8* input, int length, uint32 key_length, const
xfree(input_reverse); xfree(input_reverse);
} }
static void crypto_rsa_public(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output)
{
crypto_rsa_common(input, length, key_length, modulus, exponent, EXPONENT_MAX_SIZE, output);
}
static void crypto_rsa_private(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output)
{
crypto_rsa_common(input, length, key_length, modulus, private_exponent, key_length, output);
}
void crypto_rsa_public_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output)
{
crypto_rsa_public(input, length, key_length, modulus, exponent, output);
}
void crypto_rsa_public_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output)
{
crypto_rsa_public(input, length, key_length, modulus, exponent, output);
}
void crypto_rsa_private_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output)
{
crypto_rsa_private(input, length, key_length, modulus, private_exponent, output);
}
void crypto_rsa_private_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output)
{
crypto_rsa_private(input, length, key_length, modulus, private_exponent, output);
}
void crypto_rsa_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output)
{
crypto_rsa_common(input, length, key_length, modulus, private_exponent, key_length, output);
}
void crypto_reverse(uint8* data, int length) void crypto_reverse(uint8* data, int length)
{ {
int i, j; int i, j;

View File

@ -78,11 +78,13 @@ struct crypto_cert_struct
X509 * px509; X509 * px509;
}; };
#define CRYPTO_SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
typedef struct crypto_sha1_struct* CryptoSha1; typedef struct crypto_sha1_struct* CryptoSha1;
CryptoSha1 crypto_sha1_init(void); CryptoSha1 crypto_sha1_init(void);
void crypto_sha1_update(CryptoSha1 sha1, const uint8* data, uint32 length); void crypto_sha1_update(CryptoSha1 sha1, const uint8* data, uint32 length);
void crypto_sha1_final(CryptoSha1 sha1, uint8* out_data); void crypto_sha1_final(CryptoSha1 sha1, uint8* out_data);
#define CRYPTO_MD5_DIGEST_LENGTH MD5_DIGEST_LENGTH
typedef struct crypto_md5_struct* CryptoMd5; typedef struct crypto_md5_struct* CryptoMd5;
CryptoMd5 crypto_md5_init(void); CryptoMd5 crypto_md5_init(void);
void crypto_md5_update(CryptoMd5 md5, const uint8* data, uint32 length); void crypto_md5_update(CryptoMd5 md5, const uint8* data, uint32 length);
@ -118,7 +120,15 @@ boolean x509_verify_cert(CryptoCert cert, rdpSettings* settings);
rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname); rdpCertData* crypto_get_cert_data(X509* xcert, char* hostname);
boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key); boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key);
void crypto_rsa_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output); #define TSSK_KEY_LENGTH 64
extern const uint8 tssk_modulus[];
extern const uint8 tssk_privateExponent[];
extern const uint8 tssk_exponent[];
void crypto_rsa_public_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output);
void crypto_rsa_public_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* exponent, uint8* output);
void crypto_rsa_private_encrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output);
void crypto_rsa_private_decrypt(const uint8* input, int length, uint32 key_length, const uint8* modulus, const uint8* private_exponent, uint8* output);
void crypto_reverse(uint8* data, int length); void crypto_reverse(uint8* data, int length);
void crypto_nonce(uint8* nonce, int size); void crypto_nonce(uint8* nonce, int size);

View File

@ -329,7 +329,7 @@ void license_encrypt_premaster_secret(rdpLicense* license)
encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE); encrypted_premaster_secret = (uint8*) xmalloc(MODULUS_MAX_SIZE);
memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE); memset(encrypted_premaster_secret, 0, MODULUS_MAX_SIZE);
crypto_rsa_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH, crypto_rsa_public_encrypt(license->premaster_secret, PREMASTER_SECRET_LENGTH,
key_length, modulus, exponent, encrypted_premaster_secret); key_length, modulus, exponent, encrypted_premaster_secret);
license->encrypted_premaster_secret->type = BB_RANDOM_BLOB; license->encrypted_premaster_secret->type = BB_RANDOM_BLOB;

View File

@ -273,26 +273,22 @@ boolean mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters
void mcs_write_domain_parameters(STREAM* s, DomainParameters* domainParameters) void mcs_write_domain_parameters(STREAM* s, DomainParameters* domainParameters)
{ {
int length; int length;
uint8 *bm, *em; STREAM* tmps;
stream_get_mark(s, bm); tmps = stream_new(stream_get_size(s));
stream_seek(s, 2); ber_write_integer(tmps, domainParameters->maxChannelIds);
ber_write_integer(tmps, domainParameters->maxUserIds);
ber_write_integer(s, domainParameters->maxChannelIds); ber_write_integer(tmps, domainParameters->maxTokenIds);
ber_write_integer(s, domainParameters->maxUserIds); ber_write_integer(tmps, domainParameters->numPriorities);
ber_write_integer(s, domainParameters->maxTokenIds); ber_write_integer(tmps, domainParameters->minThroughput);
ber_write_integer(s, domainParameters->numPriorities); ber_write_integer(tmps, domainParameters->maxHeight);
ber_write_integer(s, domainParameters->minThroughput); ber_write_integer(tmps, domainParameters->maxMCSPDUsize);
ber_write_integer(s, domainParameters->maxHeight); ber_write_integer(tmps, domainParameters->protocolVersion);
ber_write_integer(s, domainParameters->maxMCSPDUsize);
ber_write_integer(s, domainParameters->protocolVersion);
stream_get_mark(s, em);
length = (em - bm) - 2;
stream_set_mark(s, bm);
length = stream_get_length(tmps);
ber_write_sequence_tag(s, length); ber_write_sequence_tag(s, length);
stream_set_mark(s, em); stream_write(s, stream_get_head(tmps), length);
stream_free(tmps);
} }
/** /**
@ -377,41 +373,36 @@ boolean mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s)
void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data) void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data)
{ {
int length; int length;
uint8 *bm, *em; STREAM* tmps;
int gcc_CCrq_length = stream_get_length(user_data); tmps = stream_new(stream_get_size(s));
stream_get_mark(s, bm);
stream_seek(s, 5);
/* callingDomainSelector (OCTET_STRING) */ /* callingDomainSelector (OCTET_STRING) */
ber_write_octet_string(s, callingDomainSelector, sizeof(callingDomainSelector)); ber_write_octet_string(tmps, callingDomainSelector, sizeof(callingDomainSelector));
/* calledDomainSelector (OCTET_STRING) */ /* calledDomainSelector (OCTET_STRING) */
ber_write_octet_string(s, calledDomainSelector, sizeof(calledDomainSelector)); ber_write_octet_string(tmps, calledDomainSelector, sizeof(calledDomainSelector));
/* upwardFlag (BOOLEAN) */ /* upwardFlag (BOOLEAN) */
ber_write_boolean(s, true); ber_write_boolean(tmps, true);
/* targetParameters (DomainParameters) */ /* targetParameters (DomainParameters) */
mcs_write_domain_parameters(s, &mcs->targetParameters); mcs_write_domain_parameters(tmps, &mcs->targetParameters);
/* minimumParameters (DomainParameters) */ /* minimumParameters (DomainParameters) */
mcs_write_domain_parameters(s, &mcs->minimumParameters); mcs_write_domain_parameters(tmps, &mcs->minimumParameters);
/* maximumParameters (DomainParameters) */ /* maximumParameters (DomainParameters) */
mcs_write_domain_parameters(s, &mcs->maximumParameters); mcs_write_domain_parameters(tmps, &mcs->maximumParameters);
/* userData (OCTET_STRING) */ /* userData (OCTET_STRING) */
ber_write_octet_string(s, user_data->data, gcc_CCrq_length); ber_write_octet_string(tmps, user_data->data, stream_get_length(user_data));
stream_get_mark(s, em);
length = (em - bm) - 5;
stream_set_mark(s, bm);
length = stream_get_length(tmps);
/* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */ /* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */
ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length); ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length);
stream_set_mark(s, em); stream_write(s, stream_get_head(tmps), length);
stream_free(tmps);
} }
/** /**
@ -425,28 +416,20 @@ void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data)
void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data) void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data)
{ {
int length; int length;
uint8 *bm, *em; STREAM* tmps;
int gcc_CCrsp_length = stream_get_length(user_data);
stream_get_mark(s, bm);
stream_seek(s, 3);
ber_write_enumerated(s, 0, MCS_Result_enum_length);
ber_write_integer(s, 0); /* calledConnectId */
tmps = stream_new(stream_get_size(s));
ber_write_enumerated(tmps, 0, MCS_Result_enum_length);
ber_write_integer(tmps, 0); /* calledConnectId */
mcs->domainParameters = mcs->targetParameters; mcs->domainParameters = mcs->targetParameters;
mcs_write_domain_parameters(s, &(mcs->domainParameters)); mcs_write_domain_parameters(tmps, &(mcs->domainParameters));
/* userData (OCTET_STRING) */ /* userData (OCTET_STRING) */
ber_write_octet_string(s, user_data->data, gcc_CCrsp_length); ber_write_octet_string(tmps, user_data->data, stream_get_length(user_data));
stream_get_mark(s, em);
length = (em - bm) - 3;
stream_set_mark(s, bm);
length = stream_get_length(tmps);
ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length); ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length);
stream_set_mark(s, em); stream_write(s, stream_get_head(tmps), length);
stream_free(tmps);
} }
/** /**

View File

@ -274,8 +274,6 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id)
static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length)
{ {
uint32 ml;
uint8* mk;
uint8* data; uint8* data;
uint32 sec_flags; uint32 sec_flags;
uint32 pad = 0; uint32 pad = 0;
@ -314,10 +312,7 @@ static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length)
{ {
data = s->p + 8; data = s->p + 8;
length = length - (data - s->data); length = length - (data - s->data);
security_mac_signature(rdp, data, length, s->p);
mk = rdp->sign_key;
ml = rdp->rc4_key_len;
security_mac_signature(mk, ml, data, length, s->p);
stream_seek(s, 8); stream_seek(s, 8);
security_encrypt(s->p, length, rdp); security_encrypt(s->p, length, rdp);
} }
@ -583,8 +578,6 @@ boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length) boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length)
{ {
uint8 cmac[8], wmac[8]; uint8 cmac[8], wmac[8];
uint32 ml;
uint8* mk;
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
{ {
@ -621,9 +614,7 @@ boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length)
stream_read(s, wmac, sizeof(wmac)); stream_read(s, wmac, sizeof(wmac));
length -= sizeof(wmac); length -= sizeof(wmac);
security_decrypt(s->p, length, rdp); security_decrypt(s->p, length, rdp);
mk = rdp->sign_key; security_mac_signature(rdp, s->p, length, cmac);
ml = rdp->rc4_key_len;
security_mac_signature(mk, ml, s->p, length, cmac);
if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { if (memcmp(wmac, cmac, sizeof(wmac)) != 0) {
printf("FATAL: invalid packet signature\n"); printf("FATAL: invalid packet signature\n");
return false; return false;

View File

@ -118,7 +118,7 @@ static void security_salted_hash(uint8* salt, uint8* input, int length, uint8* s
{ {
CryptoMd5 md5; CryptoMd5 md5;
CryptoSha1 sha1; CryptoSha1 sha1;
uint8 sha1_digest[20]; uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */ /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */
@ -133,7 +133,7 @@ static void security_salted_hash(uint8* salt, uint8* input, int length, uint8* s
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */ /* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */
md5 = crypto_md5_init(); md5 = crypto_md5_init();
crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */ crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */
crypto_md5_update(md5, sha1_digest, 20); /* SHA1_Digest */ crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
crypto_md5_final(md5, output); crypto_md5_final(md5, output);
} }
@ -201,7 +201,7 @@ void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* o
CryptoMd5 md5; CryptoMd5 md5;
CryptoSha1 sha1; CryptoSha1 sha1;
uint8 length_le[4]; uint8 length_le[4];
uint8 sha1_digest[20]; uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
/* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */ /* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */
@ -219,23 +219,23 @@ void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* o
md5 = crypto_md5_init(); md5 = crypto_md5_init();
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */ crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
crypto_md5_update(md5, sha1_digest, 20); /* SHA1_Digest */ crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
crypto_md5_final(md5, output); crypto_md5_final(md5, output);
} }
void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uint32 length, uint8* output) void security_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, uint8* output)
{ {
CryptoMd5 md5; CryptoMd5 md5;
CryptoSha1 sha1; CryptoSha1 sha1;
uint8 length_le[4]; uint8 length_le[4];
uint8 md5_digest[16]; uint8 md5_digest[CRYPTO_MD5_DIGEST_LENGTH];
uint8 sha1_digest[20]; uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
security_uint32_le(length_le, length); /* length must be little-endian */ security_uint32_le(length_le, length); /* length must be little-endian */
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */ /* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
sha1 = crypto_sha1_init(); sha1 = crypto_sha1_init();
crypto_sha1_update(sha1, mac_key, mac_key_length); /* MacKeyN */ crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */ crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */ crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */
crypto_sha1_update(sha1, data, length); /* data */ crypto_sha1_update(sha1, data, length); /* data */
@ -243,9 +243,43 @@ void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uin
/* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */ /* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */
md5 = crypto_md5_init(); md5 = crypto_md5_init();
crypto_md5_update(md5, mac_key, mac_key_length); /* MacKeyN */ crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */ crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
crypto_md5_update(md5, sha1_digest, 20); /* SHA1_Digest */ crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
crypto_md5_final(md5, md5_digest);
memcpy(output, md5_digest, 8);
}
void security_salted_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, boolean encryption, uint8* output)
{
CryptoMd5 md5;
CryptoSha1 sha1;
uint8 length_le[4];
uint8 use_count_le[4];
uint8 md5_digest[CRYPTO_MD5_DIGEST_LENGTH];
uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
security_uint32_le(length_le, length); /* length must be little-endian */
if (encryption)
security_uint32_le(use_count_le, rdp->encrypt_use_count);
else
security_uint32_le(use_count_le, rdp->decrypt_use_count);
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
sha1 = crypto_sha1_init();
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */
crypto_sha1_update(sha1, data, length); /* data */
crypto_sha1_update(sha1, use_count_le, sizeof(use_count_le)); /* encryptionCount */
crypto_sha1_final(sha1, sha1_digest);
/* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */
md5 = crypto_md5_init();
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
crypto_md5_final(md5, md5_digest); crypto_md5_final(md5, md5_digest);
memcpy(output, md5_digest, 8); memcpy(output, md5_digest, 8);
@ -313,7 +347,8 @@ boolean security_establish_keys(uint8* client_random, rdpRdp* rdp)
if (settings->encryption_method == ENCRYPTION_METHOD_FIPS) if (settings->encryption_method == ENCRYPTION_METHOD_FIPS)
{ {
CryptoSha1 sha1; CryptoSha1 sha1;
uint8 client_encrypt_key_t[21], client_decrypt_key_t[21]; uint8 client_encrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1];
uint8 client_decrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1];
printf("FIPS Compliant encryption level.\n"); printf("FIPS Compliant encryption level.\n");
@ -379,7 +414,7 @@ boolean security_establish_keys(uint8* client_random, rdpRdp* rdp)
boolean security_key_update(uint8* key, uint8* update_key, int key_len) boolean security_key_update(uint8* key, uint8* update_key, int key_len)
{ {
uint8 sha1h[20]; uint8 sha1h[CRYPTO_SHA1_DIGEST_LENGTH];
CryptoMd5 md5; CryptoMd5 md5;
CryptoSha1 sha1; CryptoSha1 sha1;
CryptoRc4 rc4; CryptoRc4 rc4;
@ -394,7 +429,7 @@ boolean security_key_update(uint8* key, uint8* update_key, int key_len)
md5 = crypto_md5_init(); md5 = crypto_md5_init();
crypto_md5_update(md5, update_key, key_len); crypto_md5_update(md5, update_key, key_len);
crypto_md5_update(md5, pad2, sizeof(pad2)); crypto_md5_update(md5, pad2, sizeof(pad2));
crypto_md5_update(md5, sha1h, 20); crypto_md5_update(md5, sha1h, sizeof(sha1h));
crypto_md5_final(md5, key); crypto_md5_final(md5, key);
rc4 = crypto_rc4_init(key, key_len); rc4 = crypto_rc4_init(key, key_len);

View File

@ -32,7 +32,8 @@ void security_mac_salt_key(uint8* session_key_blob, uint8* client_random, uint8*
void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output); void security_licensing_encryption_key(uint8* session_key_blob, uint8* client_random, uint8* server_random, uint8* output);
void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output); void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* output);
void security_mac_signature(uint8* mac_key, int mac_key_length, uint8* data, uint32 length, uint8* output); void security_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, uint8* output);
void security_salted_mac_signature(rdpRdp *rdp, uint8* data, uint32 length, boolean encryption, uint8* output);
boolean security_establish_keys(uint8* client_random, rdpRdp* rdp); boolean security_establish_keys(uint8* client_random, rdpRdp* rdp);
boolean security_encrypt(uint8* data, int length, rdpRdp* rdp); boolean security_encrypt(uint8* data, int length, rdpRdp* rdp);