Esempio n. 1
0
void gcc_read_server_security_data(STREAM* s, rdpSettings *settings)
{
	uint32 encryptionMethod;
	uint32 encryptionLevel;
	uint32 serverRandomLen;
	uint32 serverCertLen;

	stream_read_uint32(s, encryptionMethod); /* encryptionMethod */
	stream_read_uint32(s, encryptionLevel); /* encryptionLevel */
	stream_read_uint32(s, serverRandomLen); /* serverRandomLen */
	stream_read_uint32(s, serverCertLen); /* serverCertLen */

	if (encryptionMethod == 0 && encryptionLevel == 0)
	{
		/* serverRandom and serverRandom must not be present */
		return;
	}

	if (serverRandomLen > 0)
	{
		/* serverRandom */
		freerdp_blob_alloc(&settings->server_random, serverRandomLen);
		memcpy(settings->server_random.data, s->p, serverRandomLen);
		stream_seek(s, serverRandomLen);
	}

	if (serverCertLen > 0)
	{
		/* serverCertificate */
		freerdp_blob_alloc(&settings->server_certificate, serverCertLen);
		memcpy(settings->server_certificate.data, s->p, serverCertLen);
		stream_seek(s, serverCertLen);
	}
}
Esempio n. 2
0
boolean gcc_read_server_security_data(STREAM* s, rdpSettings *settings)
{
	uint32 serverRandomLen;
	uint32 serverCertLen;
	uint8* data;
	uint32 len;

	stream_read_uint32(s, settings->encryption_method); /* encryptionMethod */
	stream_read_uint32(s, settings->encryption_level); /* encryptionLevel */

	if (settings->encryption_method == 0 && settings->encryption_level == 0)
	{
		/* serverRandom and serverRandom must not be present */
		settings->encryption = false;
		settings->encryption_method = ENCRYPTION_METHOD_NONE;
		settings->encryption_level = ENCRYPTION_LEVEL_NONE;
		return true;
	}

	stream_read_uint32(s, serverRandomLen); /* serverRandomLen */
	stream_read_uint32(s, serverCertLen); /* serverCertLen */

	if (serverRandomLen > 0)
	{
		/* serverRandom */
		freerdp_blob_alloc(&settings->server_random, serverRandomLen);
		memcpy(settings->server_random.data, s->p, serverRandomLen);
		stream_seek(s, serverRandomLen);
	}
	else
	{
		return false;
	}

	if (serverCertLen > 0)
	{
		/* serverCertificate */
		freerdp_blob_alloc(&settings->server_certificate, serverCertLen);
		memcpy(settings->server_certificate.data, s->p, serverCertLen);
		stream_seek(s, serverCertLen);
		certificate_free(settings->server_cert);
		settings->server_cert = certificate_new();
		data = settings->server_certificate.data;
		len = settings->server_certificate.length;
		if (!certificate_read_server_certificate(settings->server_cert, data, len))
		{
			return false;
		}
	}
	else
	{
		return false;
	}

	return true;
}
Esempio n. 3
0
static boolean certificate_process_server_public_key(rdpCertificate* certificate, STREAM* s, uint32 length)
{
	uint8 magic[4];
	uint32 keylen;
	uint32 bitlen;
	uint32 datalen;
	uint32 modlen;

	memcpy(magic, s->p, 4);

	if (memcmp(magic, "RSA1", 4) != 0)
	{
		printf("gcc_process_server_public_key: magic error\n");
		return false;
	}

	stream_seek(s, 4);
	stream_read_uint32(s, keylen);
	stream_read_uint32(s, bitlen);
	stream_read_uint32(s, datalen);
	memcpy(certificate->cert_info.exponent, s->p, 4);
	stream_seek(s, 4);
	modlen = keylen - 8;
	freerdp_blob_alloc(&(certificate->cert_info.modulus), modlen);
	memcpy(certificate->cert_info.modulus.data, s->p, modlen);
	stream_seek(s, keylen);

	return true;
}
Esempio n. 4
0
rdpBlob* crypto_kdcmsg_decrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
{
	rdpBlob* decmsg;
	uint8* K1;
	uint8* K3;
	uint32 len;
	krbEdata* edata;
	CryptoRc4 rc4;
	K1 = xzalloc(16);
	K3 = xzalloc(16);
	len = msg->length;
	edata = xzalloc(len);
	HMAC(EVP_md5(), (void*) key, 16, (uint8*) &msgtype, 4, (void*) K1, NULL);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*) msg->data , 16, (void*) K3, NULL);
	rc4 = crypto_rc4_init(K3, 16);
	crypto_rc4(rc4, len - 16, (uint8*)(((uint8*) msg->data) + 16), (uint8*) edata->Confounder);
	crypto_rc4_free(rc4);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL);
	if(memcmp(msg->data, &edata->Checksum, 16))
	{
		xfree(edata) ;
		xfree(K1) ;
		xfree(K3) ;
		return NULL;
	}
	decmsg = xnew(rdpBlob);
	freerdp_blob_alloc(decmsg, len);
	memcpy(decmsg->data, edata, len);
	xfree(K1);
	xfree(K3);
	xfree(edata);
	return decmsg;
}
Esempio n. 5
0
rdpBlob* crypto_kdcmsg_encrypt_rc4(rdpBlob* msg, uint8* key, uint32 msgtype)
{
	rdpBlob* encmsg;
	uint8* K1;
	uint8* K3;
	uint32 len;
	krbEdata* edata;
	CryptoRc4 rc4;
	K1 = xzalloc(16);
	K3 = xzalloc(16);
	len = ((msg->length > 16) ? msg->length : 16);
	len += sizeof(krbEdata);
	edata = xzalloc(len);
	encmsg = xnew(rdpBlob);
	freerdp_blob_alloc(encmsg, len);
	HMAC(EVP_md5(), (void*) key, 16, (uint8*)&msgtype, 4, (void*) K1, NULL);
	crypto_nonce((uint8*)(edata->Confounder), 8);
	memcpy(&(edata->data[0]), msg->data, msg->length);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*)edata->Confounder, len - 16, (void*)&(edata->Checksum), NULL);
	HMAC(EVP_md5(), (void*) K1, 16, (uint8*)&(edata->Checksum), 16, (void*)K3, NULL);
	memcpy(encmsg->data, &(edata->Checksum), 16);
	rc4 = crypto_rc4_init(K3, 16);
	crypto_rc4(rc4, len - 16, (uint8*) edata->Confounder, (uint8*)(((uint8*) encmsg->data) + 16));
	crypto_rc4_free(rc4);
	xfree(K1);
	xfree(K3);
	xfree(edata);
	return encmsg;
}
Esempio n. 6
0
void credssp_encrypt_public_key(rdpCredssp* credssp, rdpBlob* d)
{
	uint8 *p;
	uint8 signature[16];
	rdpBlob encrypted_public_key;
	NTLMSSP *ntlmssp = credssp->ntlmssp;

	freerdp_blob_alloc(d, credssp->public_key.length + 16);
	ntlmssp_encrypt_message(ntlmssp, &credssp->public_key, &encrypted_public_key, signature);

#ifdef WITH_DEBUG_NLA
	printf("Public Key (length = %d)\n", credssp->public_key.length);
	freerdp_hexdump(credssp->public_key.data, credssp->public_key.length);
	printf("\n");

	printf("Encrypted Public Key (length = %d)\n", encrypted_public_key.length);
	freerdp_hexdump(encrypted_public_key.data, encrypted_public_key.length);
	printf("\n");

	printf("Signature\n");
	freerdp_hexdump(signature, 16);
	printf("\n");
#endif

	p = (uint8*) d->data;
	memcpy(p, signature, 16); /* Message Signature */
	memcpy(&p[16], encrypted_public_key.data, encrypted_public_key.length); /* Encrypted Public Key */

	freerdp_blob_free(&encrypted_public_key);
}
Esempio n. 7
0
void credssp_encrypt_ts_credentials(rdpCredssp* credssp, rdpBlob* d)
{
	uint8 *p;
	uint8 signature[16];
	rdpBlob encrypted_ts_credentials;
	NTLMSSP *ntlmssp = credssp->ntlmssp;

	freerdp_blob_alloc(d, credssp->ts_credentials.length + 16);
	ntlmssp_encrypt_message(ntlmssp, &credssp->ts_credentials, &encrypted_ts_credentials, signature);

#ifdef WITH_DEBUG_NLA
	printf("TSCredentials (length = %d)\n", credssp->ts_credentials.length);
	freerdp_hexdump(credssp->ts_credentials.data, credssp->ts_credentials.length);
	printf("\n");

	printf("Encrypted TSCredentials (length = %d)\n", encrypted_ts_credentials.length);
	freerdp_hexdump(encrypted_ts_credentials.data, encrypted_ts_credentials.length);
	printf("\n");

	printf("Signature\n");
	freerdp_hexdump(signature, 16);
	printf("\n");
#endif

	p = (uint8*) d->data;
	memcpy(p, signature, 16); /* Message Signature */
	memcpy(&p[16], encrypted_ts_credentials.data, encrypted_ts_credentials.length); /* Encrypted TSCredentials */

	freerdp_blob_free(&encrypted_ts_credentials);
}
Esempio n. 8
0
boolean crypto_cert_get_public_key(CryptoCert cert, rdpBlob* public_key)
{
	uint8* p;
	int length;
	boolean status = true;
	EVP_PKEY* pkey = NULL;

	pkey = X509_get_pubkey(cert->px509);

	if (!pkey)
	{
		printf("crypto_cert_get_public_key: X509_get_pubkey() failed\n");
		status = false;
		goto exit;
	}

	length = i2d_PublicKey(pkey, NULL);

	if (length < 1)
	{
		printf("crypto_cert_get_public_key: i2d_PublicKey() failed\n");
		status = false;
		goto exit;
	}

	freerdp_blob_alloc(public_key, length);
	p = (uint8*) public_key->data;
	i2d_PublicKey(pkey, &p);

exit:
	if (pkey)
		EVP_PKEY_free(pkey);

	return status;
}
Esempio n. 9
0
int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdpBlob* pubKeyAuth)
{
	STREAM* s;
	int length;
	int status;
	uint32 version;

	s = transport_recv_stream_init(credssp->transport, 2048);
	status = transport_read(credssp->transport, s);

	if (status < 0)
		return -1;

	/* TSRequest */
	ber_read_sequence_tag(s, &length);
	ber_read_contextual_tag(s, 0, &length, True);
	ber_read_integer(s, &version);

	/* [1] negoTokens (NegoData) */
	if (ber_read_contextual_tag(s, 1, &length, True) != False)
	{
		ber_read_sequence_tag(s, &length); /* SEQUENCE OF NegoDataItem */
		ber_read_sequence_tag(s, &length); /* NegoDataItem */
		ber_read_contextual_tag(s, 0, &length, True); /* [0] negoToken */
		ber_read_octet_string(s, &length); /* OCTET STRING */
		freerdp_blob_alloc(negoToken, length);
		stream_read(s, negoToken->data, length);
	}

	/* [2] authInfo (OCTET STRING) */
	if (ber_read_contextual_tag(s, 2, &length, True) != False)
	{
		ber_read_octet_string(s, &length); /* OCTET STRING */
		freerdp_blob_alloc(authInfo, length);
		stream_read(s, authInfo->data, length);
	}

	/* [3] pubKeyAuth (OCTET STRING) */
	if (ber_read_contextual_tag(s, 3, &length, True) != False)
	{
		ber_read_octet_string(s, &length); /* OCTET STRING */
		freerdp_blob_alloc(pubKeyAuth, length);
		stream_read(s, pubKeyAuth->data, length);
	}

	return 0;
}
Esempio n. 10
0
void credssp_encode_ts_credentials(rdpCredssp* credssp)
{
	STREAM* s;
	int length;

	s = stream_new(0);
	length = credssp_skip_ts_credentials(credssp);
	freerdp_blob_alloc(&credssp->ts_credentials, length);
	s->p = s->data = credssp->ts_credentials.data;
	s->size = length;

	credssp_write_ts_credentials(credssp, s);
}
Esempio n. 11
0
void credssp_encode_ts_credentials(rdpCredssp* credssp)
{
	STREAM* s;
	int length;

	s = stream_new(0);
	length = credssp_skip_ts_credentials(credssp);
	freerdp_blob_alloc(&credssp->ts_credentials, length);
	stream_attach(s, credssp->ts_credentials.data, length);

	credssp_write_ts_credentials(credssp, s);
	stream_detach(s);
	stream_free(s);
}
Esempio n. 12
0
rdpBlob* crypto_kdcmsg_cksum_hmacmd5(rdpBlob* msg, uint8* key, uint32 msgtype)
{
	rdpBlob* cksum;
	uint8* Ksign;
	uint8* tmpdata;
	uint8* tmp;
	CryptoMd5 md5;
	Ksign = xzalloc(16);
	tmp = xzalloc(16);
	cksum = xnew(rdpBlob);
	freerdp_blob_alloc(cksum, 16);
	tmpdata = xzalloc(msg->length + 4);
	HMAC(EVP_md5(), (void*) key, 16, (uint8*)"signaturekey\0", 13, (void*) Ksign, NULL);
	memcpy(tmpdata, (void*)&msgtype, 4);
	memcpy(tmpdata + 4, msg->data, msg->length);
	md5 = crypto_md5_init();
	crypto_md5_update(md5, tmpdata, msg->length + 4);
	crypto_md5_final(md5, tmp);
	HMAC(EVP_md5(), (void*) Ksign, 16, (uint8*)tmp, 16, (void*) cksum->data, NULL);
	return cksum;
}
Esempio n. 13
0
void gcc_write_server_security_data(STREAM* s, rdpSettings* settings)
{
	CryptoMd5 md5;
	uint8* sigData;
	int expLen, keyLen, sigDataLen;
	uint8 encryptedSignature[TSSK_KEY_LENGTH];
	uint8 signature[sizeof(initial_signature)];
	uint32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen;

	if (!settings->encryption)
	{
		settings->encryption_method = ENCRYPTION_METHOD_NONE;
		settings->encryption_level = ENCRYPTION_LEVEL_NONE;
	}
	else if ((settings->encryption_method & ENCRYPTION_METHOD_FIPS) != 0)
	{
		settings->encryption_method = ENCRYPTION_METHOD_FIPS;
	}
	else if ((settings->encryption_method & ENCRYPTION_METHOD_128BIT) != 0)
	{
		settings->encryption_method = ENCRYPTION_METHOD_128BIT;
	}
	else if ((settings->encryption_method & ENCRYPTION_METHOD_40BIT) != 0)
	{
		settings->encryption_method = ENCRYPTION_METHOD_40BIT;
	}

	if (settings->encryption_method != ENCRYPTION_METHOD_NONE)
		settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;

	headerLen = 12;
	keyLen = 0;
	wPublicKeyBlobLen = 0;
	serverRandomLen = 0;
	serverCertLen = 0;

	if (settings->encryption_method != ENCRYPTION_METHOD_NONE ||
	    settings->encryption_level != ENCRYPTION_LEVEL_NONE)
	{
		serverRandomLen = 32;

		keyLen = settings->server_key->modulus.length;
		expLen = sizeof(settings->server_key->exponent);
		wPublicKeyBlobLen = 4; /* magic (RSA1) */
		wPublicKeyBlobLen += 4; /* keylen */
		wPublicKeyBlobLen += 4; /* bitlen */
		wPublicKeyBlobLen += 4; /* datalen */
		wPublicKeyBlobLen += expLen;
		wPublicKeyBlobLen += keyLen;
		wPublicKeyBlobLen += 8; /* 8 bytes of zero padding */

		serverCertLen = 4; /* dwVersion */
		serverCertLen += 4; /* dwSigAlgId */
		serverCertLen += 4; /* dwKeyAlgId */
		serverCertLen += 2; /* wPublicKeyBlobType */
		serverCertLen += 2; /* wPublicKeyBlobLen */
		serverCertLen += wPublicKeyBlobLen;
		serverCertLen += 2; /* wSignatureBlobType */
		serverCertLen += 2; /* wSignatureBlobLen */
		serverCertLen += sizeof(encryptedSignature); /* SignatureBlob */
		serverCertLen += 8; /* 8 bytes of zero padding */

		headerLen += sizeof(serverRandomLen);
		headerLen += sizeof(serverCertLen);
		headerLen += serverRandomLen;
		headerLen += serverCertLen;
	}

	gcc_write_user_data_header(s, SC_SECURITY, headerLen);

	stream_write_uint32(s, settings->encryption_method); /* encryptionMethod */
	stream_write_uint32(s, settings->encryption_level); /* encryptionLevel */

	if (settings->encryption_method == ENCRYPTION_METHOD_NONE &&
	    settings->encryption_level == ENCRYPTION_LEVEL_NONE)
	{
		return;
	}

	stream_write_uint32(s, serverRandomLen); /* serverRandomLen */
	stream_write_uint32(s, serverCertLen); /* serverCertLen */

	freerdp_blob_alloc(settings->server_random, serverRandomLen);
	crypto_nonce(settings->server_random->data, serverRandomLen);
	stream_write(s, settings->server_random->data, serverRandomLen);

	sigData = stream_get_tail(s);

	stream_write_uint32(s, CERT_CHAIN_VERSION_1); /* dwVersion (4 bytes) */
	stream_write_uint32(s, SIGNATURE_ALG_RSA); /* dwSigAlgId */
	stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* dwKeyAlgId */
	stream_write_uint16(s, BB_RSA_KEY_BLOB); /* wPublicKeyBlobType */

	stream_write_uint16(s, wPublicKeyBlobLen); /* wPublicKeyBlobLen */
	stream_write(s, "RSA1", 4); /* magic */
	stream_write_uint32(s, keyLen + 8); /* keylen */
	stream_write_uint32(s, keyLen * 8); /* bitlen */
	stream_write_uint32(s, keyLen - 1); /* datalen */

	stream_write(s, settings->server_key->exponent, expLen);
	stream_write(s, settings->server_key->modulus.data, keyLen);
	stream_write_zero(s, 8);

	sigDataLen = stream_get_tail(s) - sigData;

	stream_write_uint16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */
	stream_write_uint16(s, keyLen + 8); /* wSignatureBlobLen */

	memcpy(signature, initial_signature, sizeof(initial_signature));

	md5 = crypto_md5_init();
	crypto_md5_update(md5, sigData, sigDataLen);
	crypto_md5_final(md5, signature);

	crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH,
		tssk_modulus, tssk_privateExponent, encryptedSignature);

	stream_write(s, encryptedSignature, sizeof(encryptedSignature));
	stream_write_zero(s, 8);
}
Esempio n. 14
0
void krb_asreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode)
{
	KrbASREQ* krb_asreq;
	PAData** pa_data;
	KrbENCData enc_data;
	KrbENCKey* enckey;
	STREAM* s;
	STREAM* paenc;
	rdpBlob msg;
	rdpBlob* encmsg;
	uint32 curlen, totlen, pai;
	uint8 *bm;
	bm = NULL;
	totlen = pai = 0;
	krb_asreq = krb_asreq_new(krb_ctx, errcode);
	pa_data = krb_asreq->padata;
	enckey = NULL;
	s = stream_new(2048);
	paenc = stream_new(100);
	
	//Begin write asn1 data reversely into stream
	stream_seek(s, 1024);
	stream_seek(paenc, 99);
	
	/* KDC-REQ-BODY (TAG 4) */
	totlen += krb_encode_req_body(s, &(krb_asreq->req_body), krb_asreq->type);
	totlen += krb_encode_contextual_tag(s, 4, totlen);

	/* padata = PA-ENC-TIMESTAMP */
	if(errcode != 0)
	{
		freerdp_blob_alloc(&msg, 21);
		memcpy(msg.data, "\x30\x13\xa0\x11\x18\x0f", 6); // PA-ENC-TS-ENC without optional pausec
		memcpy(((uint8*) msg.data) + 6, krb_asreq->req_body.from, 15);
		enckey = string2key(&(krb_ctx->passwd), krb_ctx->enctype);
		encmsg = crypto_kdcmsg_encrypt(&msg, enckey, 1); //RFC4757 section 3 for msgtype (T=1)
		enc_data.enctype = enckey->enctype;
		enc_data.kvno = -1;
		enc_data.encblob.data = encmsg->data;
		enc_data.encblob.length = encmsg->length;
		curlen = krb_encode_encrypted_data(paenc, &enc_data);
		freerdp_blob_free(&msg);
		msg.data = paenc->p;
		msg.length = curlen;

		/* padata = PA-ENC-TIMESTAMP */
		(*(pa_data + pai))->type = 2;
		(*(pa_data + pai))->value = msg;
		pai++;
		freerdp_blob_free(encmsg);
		xfree(encmsg);
	}
	
	freerdp_blob_alloc(&msg, 7);
	memcpy(msg.data, "\x30\x05\xa0\03\x01\x01", 6); // asn1 data
	*((uint8*)msg.data + 6) = krb_asreq->pa_pac_request;

	/* padata = PA-PAC-REQUEST */
	(*(pa_data + pai))->type = 128;
	(*(pa_data + pai))->value = msg;

	*(pa_data + ++pai) = NULL;

	/* padata (TAG 3) */
	curlen = krb_encode_padata(s, pa_data);
	totlen += curlen + krb_encode_contextual_tag(s, 3, curlen);

	/* MSGTYPE = AS-REQ (TAG 2) */
	totlen += krb_encode_uint8(s, 2, krb_asreq->type);

	/* KERBEROS PROTOCOL VERSION NO (TAG 1)*/
	totlen += krb_encode_uint8(s, 1, krb_asreq->pvno);

	totlen += krb_encode_sequence_tag(s, totlen);
	totlen += krb_encode_application_tag(s, krb_asreq->type, totlen);
	totlen += krb_encode_recordmark(s, totlen);

	/* READY SEND */
	krb_tcp_send(krb_ctx, s->p, totlen);

	/* save stuff */
	krb_ctx->askey = enckey;
	krb_ctx->nonce = krb_asreq->req_body.nonce;
	xfree(krb_ctx->sname);
	krb_ctx->sname = xstrdup(krb_asreq->req_body.sname);
	krb_ctx->ctime = get_local_time(krb_asreq->req_body.from);
	krb_ctx->state = KRB_ASREQ_OK;

	/* clean up */
	freerdp_blob_free(&msg);
	stream_free(s);
	stream_free(paenc);
	krb_free_asreq(krb_asreq);
	xfree(krb_asreq);
}
Esempio n. 15
0
boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 flags;
	uint16 length;
	rdpRedirection* redirection = rdp->redirection;

	stream_read_uint16(s, flags); /* flags (2 bytes) */
	stream_read_uint16(s, length); /* length (2 bytes) */
	stream_read_uint32(s, redirection->sessionID); /* sessionID (4 bytes) */
	stream_read_uint32(s, redirection->flags); /* redirFlags (4 bytes) */

	DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID);

#ifdef WITH_DEBUG_REDIR
	rdp_print_redirection_flags(redirection->flags);
#endif

	if (redirection->flags & LB_TARGET_NET_ADDRESS)
	{
		freerdp_string_read_length32(s, &redirection->targetNetAddress, rdp->settings->uniconv);
		DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii);
	}

	if (redirection->flags & LB_LOAD_BALANCE_INFO)
	{
		uint32 loadBalanceInfoLength;
		stream_read_uint32(s, loadBalanceInfoLength);
		freerdp_blob_alloc(&redirection->loadBalanceInfo, loadBalanceInfoLength);
		stream_read(s, redirection->loadBalanceInfo.data, loadBalanceInfoLength);
#ifdef WITH_DEBUG_REDIR
		DEBUG_REDIR("loadBalanceInfo:");
		freerdp_hexdump(redirection->loadBalanceInfo.data, redirection->loadBalanceInfo.length);
#endif
	}

	if (redirection->flags & LB_USERNAME)
	{
		freerdp_string_read_length32(s, &redirection->username, rdp->settings->uniconv);
		DEBUG_REDIR("username: %s", redirection->username.ascii);
	}

	if (redirection->flags & LB_DOMAIN)
	{
		freerdp_string_read_length32(s, &redirection->domain, rdp->settings->uniconv);
		DEBUG_REDIR("domain: %s", redirection->domain.ascii);
	}

	if (redirection->flags & LB_PASSWORD)
	{
		freerdp_string_read_length32(s, &redirection->password, rdp->settings->uniconv);
		DEBUG_REDIR("password: %s", redirection->password.ascii);
	}

	if (redirection->flags & LB_TARGET_FQDN)
	{
		freerdp_string_read_length32(s, &redirection->targetFQDN, rdp->settings->uniconv);
		DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii);
	}

	if (redirection->flags & LB_TARGET_NETBIOS_NAME)
	{
		freerdp_string_read_length32(s, &redirection->targetNetBiosName, rdp->settings->uniconv);
		DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii);
	}

	if (redirection->flags & LB_CLIENT_TSV_URL)
	{
		freerdp_string_read_length32(s, &redirection->tsvUrl, rdp->settings->uniconv);
		DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii);
	}

	if (redirection->flags & LB_TARGET_NET_ADDRESSES)
	{
		uint32 count;
		uint32 targetNetAddressesLength;

		stream_read_uint32(s, targetNetAddressesLength);

		stream_read_uint32(s, redirection->targetNetAddressesCount);
		count = redirection->targetNetAddressesCount;

		redirection->targetNetAddresses = (rdpString*) xzalloc(count * sizeof(rdpString));

		while (count > 0)
		{
			freerdp_string_read_length32(s, redirection->targetNetAddresses, rdp->settings->uniconv);
			DEBUG_REDIR("targetNetAddresses: %s", redirection->targetNetAddresses->ascii);
			redirection->targetNetAddresses++;
			count--;
		}
	}

	stream_seek(s, 8); /* pad (8 bytes) */

	if (redirection->flags & LB_NOREDIRECT)
		return True;
	else
		return rdp_client_redirect(rdp);
}
Esempio n. 16
0
boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s)
{
	uint16 flags;
	uint16 length;
	rdpRedirection* redirection = rdp->redirection;

	stream_read_uint16(s, flags); /* flags (2 bytes) */
	stream_read_uint16(s, length); /* length (2 bytes) */
	stream_read_uint32(s, redirection->sessionID); /* sessionID (4 bytes) */
	stream_read_uint32(s, redirection->flags); /* redirFlags (4 bytes) */

	DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, redirection->sessionID);


	if (redirection->flags & LB_TARGET_NET_ADDRESS)
	{
		freerdp_string_read_length32(s, &redirection->targetNetAddress, rdp->settings->uniconv);
		DEBUG_REDIR("targetNetAddress: %s", redirection->targetNetAddress.ascii);
	}

	if (redirection->flags & LB_LOAD_BALANCE_INFO)
	{
		uint32 loadBalanceInfoLength;
		stream_read_uint32(s, loadBalanceInfoLength);
		freerdp_blob_alloc(&redirection->loadBalanceInfo, loadBalanceInfoLength);
		stream_read(s, redirection->loadBalanceInfo.data, loadBalanceInfoLength);
	}

	if (redirection->flags & LB_USERNAME)
	{
		freerdp_string_read_length32(s, &redirection->username, rdp->settings->uniconv);
		DEBUG_REDIR("username: %s", redirection->username.ascii);
	}

	if (redirection->flags & LB_DOMAIN)
	{
		freerdp_string_read_length32(s, &redirection->domain, rdp->settings->uniconv);
		DEBUG_REDIR("domain: %s", redirection->domain.ascii);
	}

	if (redirection->flags & LB_PASSWORD)
	{
		uint32 passwordLength;
		stream_read_uint32(s, passwordLength);	/* Note: length (hopefully) includes double zero termination */
		freerdp_blob_alloc(&redirection->password_cookie, passwordLength);
		stream_read(s, redirection->password_cookie.data, passwordLength);

	}

	if (redirection->flags & LB_TARGET_FQDN)
	{
		freerdp_string_read_length32(s, &redirection->targetFQDN, rdp->settings->uniconv);
		DEBUG_REDIR("targetFQDN: %s", redirection->targetFQDN.ascii);
	}

	if (redirection->flags & LB_TARGET_NETBIOS_NAME)
	{
		freerdp_string_read_length32(s, &redirection->targetNetBiosName, rdp->settings->uniconv);
		DEBUG_REDIR("targetNetBiosName: %s", redirection->targetNetBiosName.ascii);
	}

	if (redirection->flags & LB_CLIENT_TSV_URL)
	{
		freerdp_string_read_length32(s, &redirection->tsvUrl, rdp->settings->uniconv);
		DEBUG_REDIR("tsvUrl: %s", redirection->tsvUrl.ascii);
	}

	if (redirection->flags & LB_TARGET_NET_ADDRESSES)
	{
		int i;
		uint32 count;
		uint32 targetNetAddressesLength;

		stream_read_uint32(s, targetNetAddressesLength);

		stream_read_uint32(s, redirection->targetNetAddressesCount);
		count = redirection->targetNetAddressesCount;

		redirection->targetNetAddresses = (rdpString*) xzalloc(count * sizeof(rdpString));

		for (i = 0; i < (int) count; i++)
		{
			freerdp_string_read_length32(s, &redirection->targetNetAddresses[i], rdp->settings->uniconv);
			DEBUG_REDIR("targetNetAddresses: %s", (&redirection->targetNetAddresses[i])->ascii);
		}
	}

	stream_seek(s, 8); /* pad (8 bytes) */

	if (redirection->flags & LB_NOREDIRECT)
		return true;
	else
		return rdp_client_redirect(rdp);
}
Esempio n. 17
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;
}
Esempio n. 18
0
void freerdp_blob_copy(rdpBlob* dstblob, rdpBlob* srcblob)
{
	freerdp_blob_alloc(dstblob, srcblob->length);
	memcpy(dstblob->data, srcblob->data, dstblob->length);
}
Esempio n. 19
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);
}