BOOL tpkt_read_header(wStream* s, UINT16* length) { BYTE version; if (Stream_GetRemainingLength(s) < 1) return FALSE; Stream_Peek_UINT8(s, version); if (version == 3) { UINT16 len; if (Stream_GetRemainingLength(s) < 4) return FALSE; Stream_Seek(s, 2); Stream_Read_UINT16_BE(s, len); if (len < 4) return FALSE; *length = len; } else { /* not a TPKT header */ *length = 0; } return TRUE; }
BOOL nego_read_request(rdpNego* nego, wStream* s) { BYTE li; BYTE c; BYTE type; tpkt_read_header(s); if (!tpdu_read_connection_request(s, &li)) return FALSE; if (li != Stream_GetRemainingLength(s) + 6) { fprintf(stderr, "Incorrect TPDU length indicator.\n"); return FALSE; } if (Stream_GetRemainingLength(s) > 8) { /* Optional routingToken or cookie, ending with CR+LF */ while (Stream_GetRemainingLength(s) > 0) { Stream_Read_UINT8(s, c); if (c != '\x0D') continue; Stream_Peek_UINT8(s, c); if (c != '\x0A') continue; Stream_Seek_UINT8(s); break; } } if (Stream_GetRemainingLength(s) >= 8) { /* rdpNegData (optional) */ Stream_Read_UINT8(s, type); /* Type */ if (type != TYPE_RDP_NEG_REQ) { fprintf(stderr, "Incorrect negotiation request type %d\n", type); return FALSE; } nego_process_negotiation_request(nego, s); } return TRUE; }
BOOL tpkt_verify_header(wStream* s) { BYTE version; Stream_Peek_UINT8(s, version); if (version == 3) return TRUE; else return FALSE; }
UINT16 tpkt_read_header(wStream* s) { BYTE version; UINT16 length; Stream_Peek_UINT8(s, version); if (version == 3) { Stream_Seek(s, 2); Stream_Read_UINT16_BE(s, length); } else { /* not a TPKT header */ length = 0; } return length; }
BOOL certificate_read_x509_certificate(rdpCertBlob* cert, rdpCertInfo* info) { wStream* s; int length; BYTE padding; UINT32 version; int modulus_length; int exponent_length; int error = 0; if (!cert || !info) return FALSE; memset(info, 0, sizeof(rdpCertInfo)); s = Stream_New(cert->data, cert->length); if (!s) return FALSE; info->Modulus = 0; if (!ber_read_sequence_tag(s, &length)) /* Certificate (SEQUENCE) */ goto error1; error++; if (!ber_read_sequence_tag(s, &length)) /* TBSCertificate (SEQUENCE) */ goto error1; error++; if (!ber_read_contextual_tag(s, 0, &length, TRUE)) /* Explicit Contextual Tag [0] */ goto error1; error++; if (!ber_read_integer(s, &version)) /* version (INTEGER) */ goto error1; error++; version++; /* serialNumber */ if (!ber_read_integer(s, NULL)) /* CertificateSerialNumber (INTEGER) */ goto error1; error++; /* signature */ if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ goto error1; error++; /* issuer */ if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */ goto error1; error++; /* validity */ if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Validity (SEQUENCE) */ goto error1; error++; /* subject */ if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* Name (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo */ if (!ber_read_sequence_tag(s, &length)) /* SubjectPublicKeyInfo (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo::AlgorithmIdentifier */ if (!ber_read_sequence_tag(s, &length) || !Stream_SafeSeek(s, length)) /* AlgorithmIdentifier (SEQUENCE) */ goto error1; error++; /* subjectPublicKeyInfo::subjectPublicKey */ if (!ber_read_bit_string(s, &length, &padding)) /* BIT_STRING */ goto error1; error++; /* RSAPublicKey (SEQUENCE) */ if (!ber_read_sequence_tag(s, &length)) /* SEQUENCE */ goto error1; error++; if (!ber_read_integer_length(s, &modulus_length)) /* modulus (INTEGER) */ goto error1; error++; /* skip zero padding, if any */ do { if (Stream_GetRemainingLength(s) < 1) goto error1; Stream_Peek_UINT8(s, padding); if (padding == 0) { if (!Stream_SafeSeek(s, 1)) goto error1; modulus_length--; } } while (padding == 0); error++; if (((int) Stream_GetRemainingLength(s)) < modulus_length) goto error1; info->ModulusLength = modulus_length; info->Modulus = (BYTE*) malloc(info->ModulusLength); if (!info->Modulus) goto error1; Stream_Read(s, info->Modulus, info->ModulusLength); error++; if (!ber_read_integer_length(s, &exponent_length)) /* publicExponent (INTEGER) */ goto error2; error++; if ((((int) Stream_GetRemainingLength(s)) < exponent_length) || (exponent_length > 4)) goto error2; Stream_Read(s, &info->exponent[4 - exponent_length], exponent_length); crypto_reverse(info->Modulus, info->ModulusLength); crypto_reverse(info->exponent, 4); Stream_Free(s, FALSE); return TRUE; error2: free(info->Modulus); info->Modulus = 0; error1: WLog_ERR(TAG, "error reading when reading certificate: part=%s error=%d", certificate_read_errors[error], error); Stream_Free(s, FALSE); return FALSE; }
static BOOL TestStream_Write(void) { BOOL rc = FALSE; UINT8 u8; UINT16 u16; UINT32 u32; UINT64 u64; const BYTE data[] = "someteststreamdata"; wStream* s = Stream_New(NULL, 100); if (!s) goto out; if (s->pointer != s->buffer) goto out; Stream_Write(s, data, sizeof(data)); if (memcmp(Stream_Buffer(s), data, sizeof(data)) == 0) rc = TRUE; if (s->pointer != s->buffer + sizeof(data)) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; Stream_Write_UINT8(s, 42); if (s->pointer != s->buffer + 1) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; Stream_Peek_UINT8(s, u8); if (u8 != 42) goto out; Stream_Write_UINT16(s, 0x1234); if (s->pointer != s->buffer + 2) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; Stream_Peek_UINT16(s, u16); if (u16 != 0x1234) goto out; Stream_Write_UINT32(s, 0x12345678UL); if (s->pointer != s->buffer + 4) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; Stream_Peek_UINT32(s, u32); if (u32 != 0x12345678UL) goto out; Stream_Write_UINT64(s, 0x1234567890ABCDEFULL); if (s->pointer != s->buffer + 8) goto out; Stream_SetPosition(s, 0); if (s->pointer != s->buffer) goto out; Stream_Peek_UINT64(s, u64); if (u64 != 0x1234567890ABCDEFULL) goto out; out: Stream_Free(s, TRUE); return rc; }