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); } }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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 freerdp_blob_copy(rdpBlob* dstblob, rdpBlob* srcblob) { freerdp_blob_alloc(dstblob, srcblob->length); memcpy(dstblob->data, srcblob->data, dstblob->length); }
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); }