libfreerdp-core: fixed encoding of nego tokens

This commit is contained in:
Marc-André Moreau 2011-07-18 14:56:08 -04:00
parent e058f3dda8
commit e75ebc0b58
4 changed files with 100 additions and 19 deletions

View File

@ -46,19 +46,29 @@ void ber_read_length(STREAM* s, int* length)
* @param length length * @param length length
*/ */
void ber_write_length(STREAM* s, int length) int ber_write_length(STREAM* s, int length)
{ {
if (length > 0x7F) if (length > 0x7F)
{ {
stream_write_uint8(s, 0x82); stream_write_uint8(s, 0x82);
stream_write_uint16_be(s, length); stream_write_uint16_be(s, length);
return 3;
} }
else else
{ {
stream_write_uint8(s, length); stream_write_uint8(s, length);
return 1;
} }
} }
int _ber_skip_length(int length)
{
if (length > 0x7F)
return 3;
else
return 1;
}
/** /**
* Read BER Universal tag. * Read BER Universal tag.
* @param s stream * @param s stream
@ -163,11 +173,15 @@ boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc)
return True; return True;
} }
boolean ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc) int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc)
{ {
stream_write_uint8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); stream_write_uint8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag));
ber_write_length(s, length); return ber_write_length(s, length) + 1;
return True; }
int ber_skip_contextual_tag(int length)
{
return _ber_skip_length(length) + 1;
} }
boolean ber_read_sequence_tag(STREAM* s, int* length) boolean ber_read_sequence_tag(STREAM* s, int* length)
@ -196,6 +210,11 @@ void ber_write_sequence_tag(STREAM* s, int length)
ber_write_length(s, length); ber_write_length(s, length);
} }
int ber_skip_sequence_tag(int length)
{
return _ber_skip_length(length) + 1;
}
boolean ber_read_sequence_of_tag(STREAM* s, int* length) boolean ber_read_sequence_of_tag(STREAM* s, int* length)
{ {
uint8 byte; uint8 byte;
@ -216,10 +235,15 @@ boolean ber_read_sequence_of_tag(STREAM* s, int* length)
* @param length length * @param length length
*/ */
void ber_write_sequence_of_tag(STREAM* s, int length) int ber_write_sequence_of_tag(STREAM* s, int length)
{ {
stream_write_uint8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE_OF)); stream_write_uint8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE_OF));
ber_write_length(s, length); return ber_write_length(s, length) + 1;
}
int ber_skip_sequence_of_tag(int length)
{
return _ber_skip_length(length) + 1;
} }
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count) boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count)
@ -272,6 +296,11 @@ void ber_write_octet_string(STREAM* s, uint8* oct_str, int length)
stream_write(s, oct_str, length); stream_write(s, oct_str, length);
} }
int ber_skip_octet_string(int length)
{
return 1 + _ber_skip_length(length) + length;
}
/** /**
* Write a BER BOOLEAN * Write a BER BOOLEAN
* @param s * @param s
@ -344,6 +373,24 @@ void ber_write_integer(STREAM* s, uint32 value)
} }
} }
int ber_skip_integer(uint32 value)
{
if (value <= 0xFF)
{
return _ber_skip_length(1) + 2;
}
else if (value <= 0xFFFF)
{
return _ber_skip_length(2) + 3;
}
else if (value <= 0xFFFFFFFF)
{
return _ber_skip_length(4) + 5;
}
return 0;
}
boolean ber_read_integer_length(STREAM* s, int* length) boolean ber_read_integer_length(STREAM* s, int* length)
{ {
ber_read_universal_tag(s, BER_TAG_INTEGER, False); ber_read_universal_tag(s, BER_TAG_INTEGER, False);

View File

@ -51,7 +51,8 @@
#define BER_PC(_pc) (_pc ? BER_CONSTRUCT : BER_PRIMITIVE) #define BER_PC(_pc) (_pc ? BER_CONSTRUCT : BER_PRIMITIVE)
void ber_read_length(STREAM* s, int* length); void ber_read_length(STREAM* s, int* length);
void ber_write_length(STREAM* s, int length); int ber_write_length(STREAM* s, int length);
int _ber_skip_length(int length);
boolean ber_read_universal_tag(STREAM* s, uint8 tag, boolean pc); boolean ber_read_universal_tag(STREAM* s, uint8 tag, boolean pc);
void ber_write_universal_tag(STREAM* s, uint8 tag, boolean pc); void ber_write_universal_tag(STREAM* s, uint8 tag, boolean pc);
boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length); boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length);
@ -60,17 +61,22 @@ boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length);
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count); boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count);
boolean ber_read_sequence_of_tag(STREAM* s, int* length); boolean ber_read_sequence_of_tag(STREAM* s, int* length);
boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc); boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc);
boolean ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc); int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc);
int ber_skip_contextual_tag(int length);
boolean ber_read_sequence_tag(STREAM* s, int* length); boolean ber_read_sequence_tag(STREAM* s, int* length);
void ber_write_sequence_tag(STREAM* s, int length); void ber_write_sequence_tag(STREAM* s, int length);
int ber_skip_sequence_tag(int length);
boolean ber_read_sequence_of_tag(STREAM* s, int* length); boolean ber_read_sequence_of_tag(STREAM* s, int* length);
void ber_write_sequence_of_tag(STREAM* s, int length); int ber_write_sequence_of_tag(STREAM* s, int length);
int ber_skip_sequence_of_tag(int length);
boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding); boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding);
boolean ber_read_octet_string(STREAM* s, int* length); boolean ber_read_octet_string(STREAM* s, int* length);
void ber_write_octet_string(STREAM* s, uint8* oct_str, int length); void ber_write_octet_string(STREAM* s, uint8* oct_str, int length);
int ber_skip_octet_string(int length);
void ber_write_boolean(STREAM* s, boolean value); void ber_write_boolean(STREAM* s, boolean value);
boolean ber_read_integer(STREAM* s, uint32* value); boolean ber_read_integer(STREAM* s, uint32* value);
void ber_write_integer(STREAM* s, uint32 value); void ber_write_integer(STREAM* s, uint32 value);
boolean ber_read_integer_length(STREAM* s, int* length); boolean ber_read_integer_length(STREAM* s, int* length);
int ber_skip_integer(uint32 value);
#endif /* __BER_H */ #endif /* __BER_H */

View File

@ -444,28 +444,56 @@ void credssp_send(rdpCredssp* credssp, BLOB* negoToken, BLOB* pubKeyAuth, BLOB*
} }
} }
#else #else
int credssp_skip_nego_token(int length)
{
return ber_skip_contextual_tag(length) + ber_skip_octet_string(length);
}
int credssp_skip_nego_data(int length)
{
length = credssp_skip_nego_token(length);
length += _ber_skip_length(length);
length += _ber_skip_length(length);
length += ber_skip_contextual_tag(length);
return length;
}
int credssp_skip_ts_request(int length)
{
length += ber_skip_integer(2);
length += ber_skip_contextual_tag(3);
length += ber_skip_sequence_tag(length);
return length;
}
void credssp_send(rdpCredssp* credssp, BLOB* negoToken, BLOB* pubKeyAuth, BLOB* authInfo) void credssp_send(rdpCredssp* credssp, BLOB* negoToken, BLOB* pubKeyAuth, BLOB* authInfo)
{ {
STREAM* s; STREAM* s;
uint8 *bm, *em;
int length; int length;
int ber_length; int header_length;
s = stream_new(2048); s = stream_new(2048);
int nego_data_length = credssp_skip_nego_data(negoToken->length);
int ts_request_length = credssp_skip_ts_request(nego_data_length);
printf("nego_data_length:%d\n", nego_data_length);
printf("ts_request_length:%d\n", ts_request_length);
/* TSRequest */ /* TSRequest */
ber_write_sequence_tag(s, length); /* SEQUENCE */ ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */
ber_write_contextual_tag(s, 0, 3, True); /* [0] version */ ber_write_contextual_tag(s, 0, 3, True); /* [0] version */
ber_write_integer(s, 2); /* INTEGER */ ber_write_integer(s, 2); /* INTEGER */
length -= 7;
/* NegoData */ /* NegoData */
ber_write_contextual_tag(s, 1, length, True); /* [1] negoTokens */ length = ber_write_contextual_tag(s, 1, nego_data_length, True); /* [1] negoTokens */
ber_write_sequence_of_tag(s, length - 2); /* SEQUENCE OF NegoDataItem */ length += ber_write_sequence_of_tag(s, nego_data_length - length); /* SEQUENCE OF NegoDataItem */
ber_write_sequence_of_tag(s, length - 4); /* NegoDataItem */ length += ber_write_sequence_of_tag(s, nego_data_length - length); /* NegoDataItem */
length -= 6;
/* negoToken */ /* NegoToken */
ber_write_contextual_tag(s, 0, length, True); /* [0] negoToken */ ber_write_contextual_tag(s, 0, nego_data_length - length, True); /* [0] negoToken */
ber_write_octet_string(s, negoToken->data, negoToken->length); /* OCTET STRING */ ber_write_octet_string(s, negoToken->data, negoToken->length); /* OCTET STRING */
transport_write(credssp->transport, s); transport_write(credssp->transport, s);

View File

@ -92,7 +92,7 @@ int tls_read(rdpTls* tls, uint8* data, int length)
break; break;
default: default:
tls_print_error("SSL_read", tls->ssl, status); //tls_print_error("SSL_read", tls->ssl, status);
return -1; return -1;
break; break;
} }