void license_generate_randoms(rdpLicense* license) { #if 0 crypto_nonce(license->client_random, CLIENT_RANDOM_LENGTH); /* ClientRandom */ crypto_nonce(license->premaster_secret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */ #else memset(license->client_random, 0, CLIENT_RANDOM_LENGTH); /* ClientRandom */ memset(license->premaster_secret, 0, PREMASTER_SECRET_LENGTH); /* PremasterSecret */ #endif }
void license_generate_randoms(rdpLicense* license) { ZeroMemory(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */ ZeroMemory(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */ #ifndef LICENSE_NULL_CLIENT_RANDOM crypto_nonce(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */ #endif #ifndef LICENSE_NULL_PREMASTER_SECRET crypto_nonce(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */ #endif }
void krb_reqbody_init(KRB_CONTEXT* krb_ctx, KDCReqBody* req_body, uint8 reqtype) { time_t t; req_body->cname = xstrdup(krb_ctx->cname); req_body->realm = xstrdup(krb_ctx->realm); if (reqtype == KRB_TAG_ASREQ) { req_body->kdc_options = 0x40000000 | 0x00800000 | 0x00010000 | 0x00000010; /* forwardable , renewable, canonicalize, renewable OK */ req_body->sname = xzalloc((strlen(req_body->realm) + 8) * sizeof(char)); strcpy(req_body->sname, KRB_SERVER); strcat(req_body->sname, req_body->realm); } else if (reqtype == KRB_TAG_TGSREQ) { req_body->kdc_options = 0x40000000 | 0x00800000 | 0x00010000; /* forwardable , renewable, canonicalize */ req_body->sname = xzalloc((strlen(krb_ctx->settings->hostname) + 10) * sizeof(char)); strcpy(req_body->sname, APP_SERVER); strcat(req_body->sname, krb_ctx->settings->hostname); } t = time(NULL); t += krb_ctx->clockskew; /* fix clockskew */ req_body->from = get_utc_time((time_t)(t)); req_body->till = get_utc_time((time_t)(t + 473040000)); req_body->rtime = get_utc_time((time_t)(t + 473040000)); crypto_nonce((uint8*) &(req_body->nonce), 4); }
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; }
static BOOL rdp_client_establish_keys(rdpRdp* rdp) { BYTE* mod; BYTE* exp; wStream* s; UINT32 length; UINT32 key_len; BYTE crypt_client_random[256 + 8]; if (!rdp->settings->DisableEncryption) { /* no RDP encryption */ return TRUE; } /* encrypt client random */ if (rdp->settings->ClientRandom) free(rdp->settings->ClientRandom); rdp->settings->ClientRandom = malloc(CLIENT_RANDOM_LENGTH); if (!rdp->settings->ClientRandom) return FALSE; ZeroMemory(crypt_client_random, sizeof(crypt_client_random)); crypto_nonce(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH); key_len = rdp->settings->RdpServerCertificate->cert_info.ModulusLength; mod = rdp->settings->RdpServerCertificate->cert_info.Modulus; exp = rdp->settings->RdpServerCertificate->cert_info.exponent; crypto_rsa_public_encrypt(rdp->settings->ClientRandom, CLIENT_RANDOM_LENGTH, key_len, mod, exp, crypt_client_random); /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; s = Stream_New(NULL, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT); length = key_len + 8; Stream_Write_UINT32(s, length); Stream_Write(s, crypt_client_random, length); Stream_SealLength(s); if (transport_write(rdp->mcs->transport, s) < 0) { return FALSE; } Stream_Free(s, TRUE); /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(rdp->settings->ClientRandom, rdp)) { return FALSE; } rdp->do_crypt = TRUE; if (rdp->settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return TRUE; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return TRUE; }
static boolean rdp_client_establish_keys(rdpRdp* rdp) { uint8 client_random[CLIENT_RANDOM_LENGTH]; uint8 crypt_client_random[256 + 8]; uint32 key_len; uint8* mod; uint8* exp; uint32 length; STREAM* s; if (rdp->settings->encryption == false) { /* no RDP encryption */ return true; } /* encrypt client random */ memset(crypt_client_random, 0, sizeof(crypt_client_random)); crypto_nonce(client_random, sizeof(client_random)); 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_public_encrypt(client_random, sizeof(client_random), key_len, mod, exp, crypt_client_random); /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; s = transport_send_stream_init(rdp->mcs->transport, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT); length = key_len + 8; stream_write_uint32(s, length); stream_write(s, crypt_client_random, length); if (transport_write(rdp->mcs->transport, s) < 0) { return false; } /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { return false; } rdp->do_crypt = true; if (rdp->settings->salted_checksum) rdp->do_secure_checksum = true; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return true; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return true; }
static boolean rdp_establish_keys(rdpRdp* rdp) { uint8 client_random[32]; uint8 crypt_client_random[256 + 8]; uint32 key_len; uint8* mod; uint8* exp; uint32 length; STREAM* s; if (rdp->settings->encryption == False) { /* no RDP encryption */ return True; } /* encrypt client random */ memset(crypt_client_random, 0, sizeof(crypt_client_random)); memset(client_random, 0x5e, 32); crypto_nonce(client_random, 32); 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); /* send crypt client random to server */ length = 7 + 8 + 4 + 4 + key_len + 8; s = transport_send_stream_init(rdp->mcs->transport, length); tpkt_write_header(s, length); tpdu_write_header(s, 2, 0xf0); per_write_choice(s, DomainMCSPDU_SendDataRequest << 2); per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0); stream_write_uint8(s, 0x70); length = (4 + 4 + key_len + 8) | 0x8000; stream_write_uint16_be(s, length); stream_write_uint32(s, 1); /* SEC_CLIENT_RANDOM */ length = key_len + 8; stream_write_uint32(s, length); memcpy(s->p, crypt_client_random, length); stream_seek(s, length); if (transport_write(rdp->mcs->transport, s) < 0) { return False; } /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(client_random, rdp)) { return False; } rdp->do_crypt = True; if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS) { uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); rdp->fips_hmac = crypto_hmac_new(); return True; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); return True; }
void krb_tgsreq_send(KRB_CONTEXT* krb_ctx, uint8 errcode) { KrbTGSREQ* krb_tgsreq; KrbAPREQ* krb_apreq; PAData** pa_data; Authenticator* krb_auth; STREAM* s; STREAM* sapreq; rdpBlob msg; uint32 curlen, totlen, tmp; uint8 *bm; bm = NULL; totlen = tmp = 0; krb_tgsreq = krb_tgsreq_new(krb_ctx, errcode); krb_auth = xnew(Authenticator); pa_data = krb_tgsreq->padata; s = stream_new(4096); sapreq = stream_new(2048); //Begin write asn1 data reversely into stream stream_seek(s, 4095); stream_seek(sapreq, 2047); /* KDC-REQ-BODY (TAG 4) */ totlen += krb_encode_req_body(s, &(krb_tgsreq->req_body), krb_tgsreq->type); stream_get_mark(s, bm); tmp = totlen; totlen += krb_encode_contextual_tag(s, 4, totlen); msg.data = bm; msg.length = tmp; /* Authenticator */ krb_auth->avno = KRB_VERSION; krb_auth->cname = krb_ctx->cname; krb_auth->crealm = krb_ctx->realm; krb_auth->cksumtype = get_cksum_type(krb_ctx->enctype); krb_auth->cksum = crypto_kdcmsg_cksum(&msg, krb_ctx->askey, 6); //RFC4757 section 3 for msgtype (T=6) krb_auth->ctime = krb_tgsreq->req_body.from; krb_auth->cusec = 0; crypto_nonce((uint8*)&(krb_auth->seqno), 4); /* PA-TGS-REQ */ krb_apreq = krb_apreq_new(krb_ctx, &(krb_ctx->asticket), krb_auth); curlen = krb_encode_apreq(sapreq, krb_apreq); msg.data = sapreq->p; msg.length = curlen; (*pa_data)->type = 1; (*pa_data)->value = msg; /* PA-DATA (TAG 3) */ curlen = krb_encode_padata(s, pa_data); totlen += curlen + krb_encode_contextual_tag(s, 3, curlen); /* MSGTYPE (TAG 2) */ totlen += krb_encode_uint8(s, 2, krb_tgsreq->type); /* VERSION NO (TAG 1) */ totlen += krb_encode_uint8(s, 1, krb_tgsreq->pvno); totlen += krb_encode_sequence_tag(s, totlen); totlen += krb_encode_application_tag(s, krb_tgsreq->type, totlen); totlen += krb_encode_recordmark(s, totlen); /* READY SEND */ krb_tcp_send(krb_ctx, s->p, totlen); /* save stuff */ krb_ctx->nonce = krb_tgsreq->req_body.nonce; xfree(krb_ctx->sname); krb_ctx->sname = xstrdup(krb_tgsreq->req_body.sname); krb_ctx->ctime = get_local_time(krb_tgsreq->req_body.from); krb_ctx->state = KRB_TGSREQ_OK; /* clean up */ freerdp_blob_free(krb_auth->cksum); xfree(krb_auth->cksum); xfree(krb_auth); krb_free_tgsreq(krb_tgsreq); xfree(krb_tgsreq); stream_free(sapreq); stream_free(s); }
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; /** * Re: settings->EncryptionLevel: * This is configured/set by the server implementation and serves the same * purpose as the "Encryption Level" setting in the RDP-Tcp configuration * dialog of Microsoft's Remote Desktop Session Host Configuration. * Re: settings->EncryptionMethods: * at this point this setting contains the client's supported encryption * methods we've received in gcc_read_client_security_data() */ if (!settings->UseRdpSecurityLayer) { /* TLS/NLA is used: disable rdp style encryption */ settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } /* verify server encryption level value */ switch (settings->EncryptionLevel) { case ENCRYPTION_LEVEL_NONE: WLog_INFO(TAG, "Active rdp encryption level: NONE"); break; case ENCRYPTION_LEVEL_FIPS: WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant"); break; case ENCRYPTION_LEVEL_HIGH: WLog_INFO(TAG, "Active rdp encryption level: HIGH"); break; case ENCRYPTION_LEVEL_LOW: WLog_INFO(TAG, "Active rdp encryption level: LOW"); break; case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE"); break; default: WLog_ERR(TAG, "Invalid server encryption level 0x%08X", settings->EncryptionLevel); WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE"); settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; } /* choose rdp encryption method based on server level and client methods */ switch (settings->EncryptionLevel) { case ENCRYPTION_LEVEL_NONE: /* The only valid method is NONE in this case */ settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; break; case ENCRYPTION_LEVEL_FIPS: /* The only valid method is FIPS in this case */ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS)) { WLog_WARN(TAG, "client does not support FIPS as required by server configuration"); } settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; break; case ENCRYPTION_LEVEL_HIGH: /* Maximum key strength supported by the server must be used (128 bit)*/ if (!(settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT)) { WLog_WARN(TAG, "client does not support 128 bit encryption method as required by server configuration"); } settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; break; case ENCRYPTION_LEVEL_LOW: case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE: /* Maximum key strength supported by the client must be used */ if (settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_56BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_56BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; else if (settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; else { WLog_WARN(TAG, "client has not announced any supported encryption methods"); settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } break; default: WLog_ERR(TAG, "internal error: unknown encryption level"); } /* log selected encryption method */ switch (settings->EncryptionMethods) { case ENCRYPTION_METHOD_NONE: WLog_INFO(TAG, "Selected rdp encryption method: NONE"); break; case ENCRYPTION_METHOD_40BIT: WLog_INFO(TAG, "Selected rdp encryption method: 40BIT"); break; case ENCRYPTION_METHOD_56BIT: WLog_INFO(TAG, "Selected rdp encryption method: 56BIT"); break; case ENCRYPTION_METHOD_128BIT: WLog_INFO(TAG, "Selected rdp encryption method: 128BIT"); break; case ENCRYPTION_METHOD_FIPS: WLog_INFO(TAG, "Selected rdp encryption method: FIPS"); break; default: WLog_ERR(TAG, "internal error: unknown encryption method"); } headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->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->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE) { return; } Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); sigData = Stream_Pointer(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->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); sigDataLen = Stream_Pointer(s) - sigData; Stream_Write_UINT16(s, BB_RSA_SIGNATURE_BLOB); /* wSignatureBlobType */ Stream_Write_UINT16(s, sizeof(encryptedSignature) + 8); /* wSignatureBlobLen */ memcpy(signature, initial_signature, sizeof(initial_signature)); md5 = crypto_md5_init(); if (!md5) { WLog_ERR(TAG, "unable to allocate a md5"); return; } 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_Zero(s, 8); }
static BOOL rdp_client_establish_keys(rdpRdp* rdp) { BYTE* mod; BYTE* exp; wStream* s; UINT32 length; UINT32 key_len; int status = 0; BOOL ret = FALSE; rdpSettings* settings; BYTE* crypt_client_random = NULL; settings = rdp->settings; if (!settings->DisableEncryption) { /* no RDP encryption */ return TRUE; } /* encrypt client random */ if (settings->ClientRandom) free(settings->ClientRandom); settings->ClientRandomLength = CLIENT_RANDOM_LENGTH; settings->ClientRandom = malloc(settings->ClientRandomLength); if (!settings->ClientRandom) return FALSE; crypto_nonce(settings->ClientRandom, settings->ClientRandomLength); key_len = settings->RdpServerCertificate->cert_info.ModulusLength; mod = settings->RdpServerCertificate->cert_info.Modulus; exp = settings->RdpServerCertificate->cert_info.exponent; /* * client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1 * for details */ crypt_client_random = calloc(1, key_len + 8); if (!crypt_client_random) return FALSE; crypto_rsa_public_encrypt(settings->ClientRandom, settings->ClientRandomLength, key_len, mod, exp, crypt_client_random); /* send crypt client random to server */ length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8; s = Stream_New(NULL, length); rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID); rdp_write_security_header(s, SEC_EXCHANGE_PKT | SEC_LICENSE_ENCRYPT_SC); length = key_len + 8; Stream_Write_UINT32(s, length); Stream_Write(s, crypt_client_random, length); Stream_SealLength(s); status = transport_write(rdp->mcs->transport, s); Stream_Free(s, TRUE); if (status < 0) goto end; rdp->do_crypt_license = TRUE; /* now calculate encrypt / decrypt and update keys */ if (!security_establish_keys(settings->ClientRandom, rdp)) goto end; rdp->do_crypt = TRUE; if (settings->SaltedChecksum) rdp->do_secure_checksum = TRUE; if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) { rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec); if (!rdp->fips_encrypt) { WLog_ERR(TAG, "unable to allocate des3 encrypt key"); goto end; } rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec); if (!rdp->fips_decrypt) { WLog_ERR(TAG, "unable to allocate des3 decrypt key"); goto end; } rdp->fips_hmac = crypto_hmac_new(); if (!rdp->fips_hmac) { WLog_ERR(TAG, "unable to allocate fips hmac"); goto end; } ret = TRUE; goto end; } rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len); if (!rdp->rc4_decrypt_key) { WLog_ERR(TAG, "unable to allocate rc4 decrypt key"); goto end; } rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len); if (!rdp->rc4_encrypt_key) { WLog_ERR(TAG, "unable to allocate rc4 encrypt key"); goto end; } ret = TRUE; end: if (crypt_client_random) free(crypt_client_random); return ret; }
void gcc_write_server_security_data(wStream* s, rdpMcs* mcs) { CryptoMd5 md5; BYTE* sigData; int expLen, keyLen, sigDataLen; BYTE encryptedSignature[TSSK_KEY_LENGTH]; BYTE signature[sizeof(initial_signature)]; UINT32 headerLen, serverRandomLen, serverCertLen, wPublicKeyBlobLen; rdpSettings* settings = mcs->settings; if (!settings->DisableEncryption) { settings->EncryptionMethods = ENCRYPTION_METHOD_NONE; settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_FIPS) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_128BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_128BIT; } else if ((settings->EncryptionMethods & ENCRYPTION_METHOD_40BIT) != 0) { settings->EncryptionMethods = ENCRYPTION_METHOD_40BIT; } if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE) settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; headerLen = 12; keyLen = 0; wPublicKeyBlobLen = 0; serverRandomLen = 0; serverCertLen = 0; if (settings->EncryptionMethods != ENCRYPTION_METHOD_NONE || settings->EncryptionLevel != ENCRYPTION_LEVEL_NONE) { serverRandomLen = 32; keyLen = settings->RdpServerRsaKey->ModulusLength; expLen = sizeof(settings->RdpServerRsaKey->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->EncryptionMethods); /* encryptionMethod */ Stream_Write_UINT32(s, settings->EncryptionLevel); /* encryptionLevel */ if (settings->EncryptionMethods == ENCRYPTION_METHOD_NONE && settings->EncryptionLevel == ENCRYPTION_LEVEL_NONE) { return; } Stream_Write_UINT32(s, serverRandomLen); /* serverRandomLen */ Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */ settings->ServerRandomLength = serverRandomLen; settings->ServerRandom = (BYTE*) malloc(serverRandomLen); crypto_nonce(settings->ServerRandom, serverRandomLen); Stream_Write(s, settings->ServerRandom, serverRandomLen); sigData = Stream_Pointer(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->RdpServerRsaKey->exponent, expLen); Stream_Write(s, settings->RdpServerRsaKey->Modulus, keyLen); Stream_Zero(s, 8); sigDataLen = Stream_Pointer(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_Zero(s, 8); }
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); }