Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
0a454fe91d
@ -163,8 +163,16 @@ if(NOT WIN32)
|
||||
add_subdirectory(channels)
|
||||
endif()
|
||||
|
||||
option(WITH_CLIENT "Build client binaries" ON)
|
||||
if(WITH_CLIENT)
|
||||
add_subdirectory(client)
|
||||
endif()
|
||||
|
||||
option(WITH_SERVER "Build server binaries" OFF)
|
||||
if(WITH_SERVER)
|
||||
add_subdirectory(server)
|
||||
endif()
|
||||
|
||||
add_subdirectory(keymaps)
|
||||
|
||||
# Source package
|
||||
|
@ -28,7 +28,7 @@
|
||||
# limitations under the License.
|
||||
#=============================================================================
|
||||
|
||||
find_path(X11_INCLUDE_DIR NAMES Xlib.h
|
||||
find_path(X11_INCLUDE_DIR NAMES X11/Xlib.h
|
||||
PATH_SUFFIXES X11
|
||||
DOC "The X11 include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The XKBFile include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The XShm include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The XTest include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The Xcursor include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The Xdamage include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The Xext include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The Xfixes include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The Xinerama include directory"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@
|
||||
# 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
|
||||
DOC "The Xv include directory"
|
||||
)
|
||||
|
@ -256,9 +256,48 @@ static boolean certificate_process_server_public_key(rdpCertificate* certificate
|
||||
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;
|
||||
}
|
||||
|
||||
@ -276,10 +315,14 @@ boolean certificate_read_server_proprietary_certificate(rdpCertificate* certific
|
||||
uint32 wPublicKeyBlobLen;
|
||||
uint32 wSignatureBlobType;
|
||||
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, 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");
|
||||
return false;
|
||||
@ -296,6 +339,7 @@ boolean certificate_read_server_proprietary_certificate(rdpCertificate* certific
|
||||
printf("certificate_read_server_proprietary_certificate: parse error 3\n");
|
||||
return false;
|
||||
}
|
||||
sigdatalen = stream_get_tail(s) - sigdata;
|
||||
stream_read_uint16(s, wSignatureBlobType);
|
||||
if (wSignatureBlobType != BB_RSA_SIGNATURE_BLOB)
|
||||
{
|
||||
@ -303,7 +347,11 @@ boolean certificate_read_server_proprietary_certificate(rdpCertificate* certific
|
||||
return false;
|
||||
}
|
||||
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");
|
||||
return false;
|
||||
|
@ -36,6 +36,9 @@
|
||||
#define CERT_PERMANENTLY_ISSUED 0x00000000
|
||||
#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_SIGNATURE_BLOB 8
|
||||
|
||||
|
@ -203,7 +203,7 @@ static boolean rdp_establish_keys(rdpRdp* rdp)
|
||||
key_len = rdp->settings->server_cert->cert_info.modulus.length;
|
||||
mod = rdp->settings->server_cert->cert_info.modulus.data;
|
||||
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 */
|
||||
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);
|
||||
else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
|
||||
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);
|
||||
|
||||
if (!ret)
|
||||
|
@ -188,7 +188,35 @@ exit:
|
||||
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;
|
||||
int output_length;
|
||||
@ -197,14 +225,14 @@ void crypto_rsa_encrypt(const uint8* input, int length, uint32 key_length, const
|
||||
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;
|
||||
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_MAX_SIZE);
|
||||
crypto_reverse(exponent_reverse, EXPONENT_MAX_SIZE);
|
||||
memcpy(exponent_reverse, exponent, exponent_size);
|
||||
crypto_reverse(exponent_reverse, exponent_size);
|
||||
memcpy(input_reverse, input, 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_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_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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -78,11 +78,13 @@ struct crypto_cert_struct
|
||||
X509 * px509;
|
||||
};
|
||||
|
||||
#define CRYPTO_SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
|
||||
typedef struct crypto_sha1_struct* CryptoSha1;
|
||||
CryptoSha1 crypto_sha1_init(void);
|
||||
void crypto_sha1_update(CryptoSha1 sha1, const uint8* data, uint32 length);
|
||||
void crypto_sha1_final(CryptoSha1 sha1, uint8* out_data);
|
||||
|
||||
#define CRYPTO_MD5_DIGEST_LENGTH MD5_DIGEST_LENGTH
|
||||
typedef struct crypto_md5_struct* CryptoMd5;
|
||||
CryptoMd5 crypto_md5_init(void);
|
||||
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);
|
||||
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_nonce(uint8* nonce, int size);
|
||||
|
||||
|
@ -329,7 +329,7 @@ void license_encrypt_premaster_secret(rdpLicense* license)
|
||||
encrypted_premaster_secret = (uint8*) xmalloc(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);
|
||||
|
||||
license->encrypted_premaster_secret->type = BB_RANDOM_BLOB;
|
||||
|
@ -273,26 +273,22 @@ boolean mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters
|
||||
void mcs_write_domain_parameters(STREAM* s, DomainParameters* domainParameters)
|
||||
{
|
||||
int length;
|
||||
uint8 *bm, *em;
|
||||
STREAM* tmps;
|
||||
|
||||
stream_get_mark(s, bm);
|
||||
stream_seek(s, 2);
|
||||
|
||||
ber_write_integer(s, domainParameters->maxChannelIds);
|
||||
ber_write_integer(s, domainParameters->maxUserIds);
|
||||
ber_write_integer(s, domainParameters->maxTokenIds);
|
||||
ber_write_integer(s, domainParameters->numPriorities);
|
||||
ber_write_integer(s, domainParameters->minThroughput);
|
||||
ber_write_integer(s, domainParameters->maxHeight);
|
||||
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);
|
||||
tmps = stream_new(stream_get_size(s));
|
||||
ber_write_integer(tmps, domainParameters->maxChannelIds);
|
||||
ber_write_integer(tmps, domainParameters->maxUserIds);
|
||||
ber_write_integer(tmps, domainParameters->maxTokenIds);
|
||||
ber_write_integer(tmps, domainParameters->numPriorities);
|
||||
ber_write_integer(tmps, domainParameters->minThroughput);
|
||||
ber_write_integer(tmps, domainParameters->maxHeight);
|
||||
ber_write_integer(tmps, domainParameters->maxMCSPDUsize);
|
||||
ber_write_integer(tmps, domainParameters->protocolVersion);
|
||||
|
||||
length = stream_get_length(tmps);
|
||||
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)
|
||||
{
|
||||
int length;
|
||||
uint8 *bm, *em;
|
||||
STREAM* tmps;
|
||||
|
||||
int gcc_CCrq_length = stream_get_length(user_data);
|
||||
|
||||
stream_get_mark(s, bm);
|
||||
stream_seek(s, 5);
|
||||
tmps = stream_new(stream_get_size(s));
|
||||
|
||||
/* callingDomainSelector (OCTET_STRING) */
|
||||
ber_write_octet_string(s, callingDomainSelector, sizeof(callingDomainSelector));
|
||||
ber_write_octet_string(tmps, callingDomainSelector, sizeof(callingDomainSelector));
|
||||
|
||||
/* calledDomainSelector (OCTET_STRING) */
|
||||
ber_write_octet_string(s, calledDomainSelector, sizeof(calledDomainSelector));
|
||||
ber_write_octet_string(tmps, calledDomainSelector, sizeof(calledDomainSelector));
|
||||
|
||||
/* upwardFlag (BOOLEAN) */
|
||||
ber_write_boolean(s, true);
|
||||
ber_write_boolean(tmps, true);
|
||||
|
||||
/* targetParameters (DomainParameters) */
|
||||
mcs_write_domain_parameters(s, &mcs->targetParameters);
|
||||
mcs_write_domain_parameters(tmps, &mcs->targetParameters);
|
||||
|
||||
/* minimumParameters (DomainParameters) */
|
||||
mcs_write_domain_parameters(s, &mcs->minimumParameters);
|
||||
mcs_write_domain_parameters(tmps, &mcs->minimumParameters);
|
||||
|
||||
/* maximumParameters (DomainParameters) */
|
||||
mcs_write_domain_parameters(s, &mcs->maximumParameters);
|
||||
mcs_write_domain_parameters(tmps, &mcs->maximumParameters);
|
||||
|
||||
/* userData (OCTET_STRING) */
|
||||
ber_write_octet_string(s, user_data->data, gcc_CCrq_length);
|
||||
|
||||
stream_get_mark(s, em);
|
||||
length = (em - bm) - 5;
|
||||
stream_set_mark(s, bm);
|
||||
ber_write_octet_string(tmps, user_data->data, stream_get_length(user_data));
|
||||
|
||||
length = stream_get_length(tmps);
|
||||
/* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */
|
||||
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)
|
||||
{
|
||||
int length;
|
||||
uint8 *bm, *em;
|
||||
|
||||
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 */
|
||||
STREAM* tmps;
|
||||
|
||||
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_write_domain_parameters(s, &(mcs->domainParameters));
|
||||
|
||||
mcs_write_domain_parameters(tmps, &(mcs->domainParameters));
|
||||
/* userData (OCTET_STRING) */
|
||||
ber_write_octet_string(s, user_data->data, gcc_CCrsp_length);
|
||||
|
||||
stream_get_mark(s, em);
|
||||
length = (em - bm) - 3;
|
||||
stream_set_mark(s, bm);
|
||||
ber_write_octet_string(tmps, user_data->data, stream_get_length(user_data));
|
||||
|
||||
length = stream_get_length(tmps);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
{
|
||||
uint32 ml;
|
||||
uint8* mk;
|
||||
uint8* data;
|
||||
uint32 sec_flags;
|
||||
uint32 pad = 0;
|
||||
@ -314,10 +312,7 @@ static uint32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length)
|
||||
{
|
||||
data = s->p + 8;
|
||||
length = length - (data - s->data);
|
||||
|
||||
mk = rdp->sign_key;
|
||||
ml = rdp->rc4_key_len;
|
||||
security_mac_signature(mk, ml, data, length, s->p);
|
||||
security_mac_signature(rdp, data, length, s->p);
|
||||
stream_seek(s, 8);
|
||||
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)
|
||||
{
|
||||
uint8 cmac[8], wmac[8];
|
||||
uint32 ml;
|
||||
uint8* mk;
|
||||
|
||||
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));
|
||||
length -= sizeof(wmac);
|
||||
security_decrypt(s->p, length, rdp);
|
||||
mk = rdp->sign_key;
|
||||
ml = rdp->rc4_key_len;
|
||||
security_mac_signature(mk, ml, s->p, length, cmac);
|
||||
security_mac_signature(rdp, s->p, length, cmac);
|
||||
if (memcmp(wmac, cmac, sizeof(wmac)) != 0) {
|
||||
printf("FATAL: invalid packet signature\n");
|
||||
return false;
|
||||
|
@ -118,7 +118,7 @@ static void security_salted_hash(uint8* salt, uint8* input, int length, uint8* s
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
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)) */
|
||||
|
||||
@ -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) */
|
||||
md5 = crypto_md5_init();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ void security_mac_data(uint8* mac_salt_key, uint8* data, uint32 length, uint8* o
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
uint8 length_le[4];
|
||||
uint8 sha1_digest[20];
|
||||
uint8 sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
|
||||
/* 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();
|
||||
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
CryptoSha1 sha1;
|
||||
uint8 length_le[4];
|
||||
uint8 md5_digest[16];
|
||||
uint8 sha1_digest[20];
|
||||
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 */
|
||||
|
||||
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
|
||||
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, length_le, sizeof(length_le)); /* length */
|
||||
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)) */
|
||||
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, 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);
|
||||
|
||||
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)
|
||||
{
|
||||
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");
|
||||
|
||||
@ -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)
|
||||
{
|
||||
uint8 sha1h[20];
|
||||
uint8 sha1h[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
CryptoRc4 rc4;
|
||||
@ -394,7 +429,7 @@ boolean security_key_update(uint8* key, uint8* update_key, int key_len)
|
||||
md5 = crypto_md5_init();
|
||||
crypto_md5_update(md5, update_key, key_len);
|
||||
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);
|
||||
|
||||
rc4 = crypto_rc4_init(key, key_len);
|
||||
|
@ -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_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_encrypt(uint8* data, int length, rdpRdp* rdp);
|
||||
|
Loading…
Reference in New Issue
Block a user