FreeRDP
er.c
1 
21 #include <freerdp/config.h>
22 
23 #include <winpr/crt.h>
24 #include <winpr/assert.h>
25 
26 #include <freerdp/crypto/er.h>
27 #include <freerdp/crypto/ber.h>
28 #include <freerdp/crypto/der.h>
29 
30 void er_read_length(wStream* s, int* length)
31 {
32  BYTE byte = 0;
33 
34  Stream_Read_UINT8(s, byte);
35 
36  if (!length)
37  return;
38 
39  *length = 0;
40  if (!s)
41  return;
42 
43  if (byte & 0x80)
44  {
45  byte &= ~(0x80);
46 
47  if (byte == 1)
48  Stream_Read_UINT8(s, *length);
49  if (byte == 2)
50  Stream_Read_UINT16_BE(s, *length);
51  }
52  else
53  {
54  *length = byte;
55  }
56 }
57 
64 int er_write_length(wStream* s, int length, BOOL flag)
65 {
66  WINPR_ASSERT(length >= 0);
67  if (flag)
68  return der_write_length(s, length);
69  else
70  return (int)ber_write_length(s, (size_t)length);
71 }
72 
73 int _er_skip_length(int length)
74 {
75  if (length > 0x7F)
76  return 3;
77  else
78  return 1;
79 }
80 
81 int er_get_content_length(int length)
82 {
83  if (length - 1 > 0x7F)
84  return length - 4;
85  else
86  return length - 2;
87 }
88 
96 BOOL er_read_universal_tag(wStream* s, BYTE tag, BOOL pc)
97 {
98  BYTE byte = 0;
99 
100  Stream_Read_UINT8(s, byte);
101 
102  if (byte != (ER_CLASS_UNIV | ER_PC(pc) | (ER_TAG_MASK & tag)))
103  return FALSE;
104 
105  return TRUE;
106 }
107 
115 void er_write_universal_tag(wStream* s, BYTE tag, BOOL pc)
116 {
117  Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag));
118 }
119 
127 BOOL er_read_application_tag(wStream* s, BYTE tag, int* length)
128 {
129  BYTE byte = 0;
130 
131  if (tag > 30)
132  {
133  Stream_Read_UINT8(s, byte);
134 
135  if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK))
136  return FALSE;
137 
138  Stream_Read_UINT8(s, byte);
139 
140  if (byte != tag)
141  return FALSE;
142 
143  er_read_length(s, length);
144  }
145  else
146  {
147  Stream_Read_UINT8(s, byte);
148 
149  if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)))
150  return FALSE;
151 
152  er_read_length(s, length);
153  }
154 
155  return TRUE;
156 }
157 
165 void er_write_application_tag(wStream* s, BYTE tag, int length, BOOL flag)
166 {
167  if (tag > 30)
168  {
169  Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK);
170  Stream_Write_UINT8(s, tag);
171  er_write_length(s, length, flag);
172  }
173  else
174  {
175  Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag));
176  er_write_length(s, length, flag);
177  }
178 }
179 
180 BOOL er_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc)
181 {
182  BYTE byte = 0;
183 
184  Stream_Read_UINT8(s, byte);
185 
186  if (byte != ((ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)))
187  {
188  Stream_Rewind(s, 1);
189  return FALSE;
190  }
191 
192  er_read_length(s, length);
193 
194  return TRUE;
195 }
196 
197 int er_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc, BOOL flag)
198 {
199  Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag));
200  return er_write_length(s, length, flag) + 1;
201 }
202 
203 int er_skip_contextual_tag(int length)
204 {
205  return _er_skip_length(length) + 1;
206 }
207 
208 BOOL er_read_sequence_tag(wStream* s, int* length)
209 {
210  BYTE byte = 0;
211 
212  Stream_Read_UINT8(s, byte);
213 
214  if (byte != ((ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_SEQUENCE_OF)))
215  return FALSE;
216 
217  er_read_length(s, length);
218 
219  return TRUE;
220 }
221 
228 int er_write_sequence_tag(wStream* s, int length, BOOL flag)
229 {
230  Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE));
231  return er_write_length(s, length, flag) + 1;
232 }
233 
234 int er_skip_sequence(int length)
235 {
236  return 1 + _er_skip_length(length) + length;
237 }
238 
239 int er_skip_sequence_tag(int length)
240 {
241  return 1 + _er_skip_length(length);
242 }
243 
244 BOOL er_read_enumerated(wStream* s, BYTE* enumerated, BYTE count)
245 {
246  int length = 0;
247 
248  er_read_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
249  er_read_length(s, &length);
250 
251  if (length == 1)
252  Stream_Read_UINT8(s, *enumerated);
253  else
254  return FALSE;
255 
256  /* check that enumerated value falls within expected range */
257  if (*enumerated + 1 > count)
258  return FALSE;
259 
260  return TRUE;
261 }
262 
263 void er_write_enumerated(wStream* s, BYTE enumerated, BYTE count, BOOL flag)
264 {
265  er_write_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
266  er_write_length(s, 1, flag);
267  Stream_Write_UINT8(s, enumerated);
268 }
269 
270 BOOL er_read_bit_string(wStream* s, int* length, BYTE* padding)
271 {
272  er_read_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
273  er_read_length(s, length);
274  Stream_Read_UINT8(s, *padding);
275 
276  return TRUE;
277 }
278 
279 BOOL er_write_bit_string_tag(wStream* s, UINT32 length, BYTE padding, BOOL flag)
280 {
281  er_write_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
282  er_write_length(s, length, flag);
283  Stream_Write_UINT8(s, padding);
284  return TRUE;
285 }
286 
287 BOOL er_read_octet_string(wStream* s, int* length)
288 {
289  if (!er_read_universal_tag(s, ER_TAG_OCTET_STRING, FALSE))
290  return FALSE;
291  er_read_length(s, length);
292 
293  return TRUE;
294 }
295 
303 void er_write_octet_string(wStream* s, BYTE* oct_str, int length, BOOL flag)
304 {
305  er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
306  er_write_length(s, length, flag);
307  Stream_Write(s, oct_str, length);
308 }
309 
310 int er_write_octet_string_tag(wStream* s, int length, BOOL flag)
311 {
312  er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
313  er_write_length(s, length, flag);
314  return 1 + _er_skip_length(length);
315 }
316 
317 int er_skip_octet_string(int length)
318 {
319  return 1 + _er_skip_length(length) + length;
320 }
321 
328 BOOL er_read_BOOL(wStream* s, BOOL* value)
329 {
330  int length = 0;
331  BYTE v = 0;
332 
333  if (!er_read_universal_tag(s, ER_TAG_BOOLEAN, FALSE))
334  return FALSE;
335  er_read_length(s, &length);
336  if (length != 1)
337  return FALSE;
338  Stream_Read_UINT8(s, v);
339  *value = (v ? TRUE : FALSE);
340  return TRUE;
341 }
342 
349 void er_write_BOOL(wStream* s, BOOL value)
350 {
351  er_write_universal_tag(s, ER_TAG_BOOLEAN, FALSE);
352  er_write_length(s, 1, FALSE);
353  Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0);
354 }
355 
356 BOOL er_read_integer(wStream* s, UINT32* value)
357 {
358  int length = 0;
359 
360  er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
361  er_read_length(s, &length);
362 
363  if (value == NULL)
364  {
365  Stream_Seek(s, length);
366  return TRUE;
367  }
368 
369  if (length == 1)
370  {
371  Stream_Read_UINT8(s, *value);
372  }
373  else if (length == 2)
374  {
375  Stream_Read_UINT16_BE(s, *value);
376  }
377  else if (length == 3)
378  {
379  BYTE byte = 0;
380  Stream_Read_UINT8(s, byte);
381  Stream_Read_UINT16_BE(s, *value);
382  *value += (byte << 16);
383  }
384  else if (length == 4)
385  {
386  Stream_Read_UINT32_BE(s, *value);
387  }
388  else
389  {
390  return FALSE;
391  }
392 
393  return TRUE;
394 }
395 
402 int er_write_integer(wStream* s, INT32 value)
403 {
404  er_write_universal_tag(s, ER_TAG_INTEGER, FALSE);
405 
406  if (value <= 127 && value >= -128)
407  {
408  er_write_length(s, 1, FALSE);
409  Stream_Write_UINT8(s, value);
410  return 2;
411  }
412  else if (value <= 32767 && value >= -32768)
413  {
414  er_write_length(s, 2, FALSE);
415  Stream_Write_INT16_BE(s, value);
416  return 3;
417  }
418  else
419  {
420  er_write_length(s, 4, FALSE);
421  Stream_Write_INT32_BE(s, value);
422  return 5;
423  }
424 }
425 
426 int er_skip_integer(INT32 value)
427 {
428  if (value <= 127 && value >= -128)
429  {
430  return _er_skip_length(1) + 2;
431  }
432  else if (value <= 32767 && value >= -32768)
433  {
434  return _er_skip_length(2) + 3;
435  }
436  else
437  {
438  return _er_skip_length(4) + 5;
439  }
440 }
441 
442 BOOL er_read_integer_length(wStream* s, int* length)
443 {
444  er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
445  er_read_length(s, length);
446  return TRUE;
447 }