~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to libfreerdp/crypto/er.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.2.5)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20141111122050-7z628f4ab38qxad5
Tags: upstream-1.1.0~git20140921.1.440916e+dfsg1
ImportĀ upstreamĀ versionĀ 1.1.0~git20140921.1.440916e+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol Implementation
 
3
 * ASN.1 Encoding Rules (BER/DER common functions)
 
4
 *
 
5
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 * Modified by Jiten Pathy
 
7
 *
 
8
 * Licensed under the Apache License, Version 2.0 (the "License");
 
9
 * you may not use this file except in compliance with the License.
 
10
 * You may obtain a copy of the License at
 
11
 *
 
12
 *       http://www.apache.org/licenses/LICENSE-2.0
 
13
 *
 
14
 * Unless required by applicable law or agreed to in writing, software
 
15
 * distributed under the License is distributed on an "AS IS" BASIS,
 
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
17
 * See the License for the specific language governing permissions and
 
18
 * limitations under the License.
 
19
 */
 
20
 
 
21
#ifdef HAVE_CONFIG_H
 
22
#include "config.h"
 
23
#endif
 
24
 
 
25
#include <winpr/crt.h>
 
26
 
 
27
#include <freerdp/crypto/er.h>
 
28
#include <freerdp/crypto/ber.h>
 
29
#include <freerdp/crypto/der.h>
 
30
 
 
31
void er_read_length(wStream* s, int* length)
 
32
{
 
33
        BYTE byte;
 
34
 
 
35
        Stream_Read_UINT8(s, byte);
 
36
 
 
37
        if (byte & 0x80)
 
38
        {
 
39
                byte &= ~(0x80);
 
40
 
 
41
                if (byte == 1)
 
42
                        Stream_Read_UINT8(s, *length);
 
43
                if (byte == 2)
 
44
                        Stream_Read_UINT16_BE(s, *length);
 
45
        }
 
46
        else
 
47
        {
 
48
                *length = byte;
 
49
        }
 
50
}
 
51
 
 
52
/**
 
53
 * Write er length.
 
54
 * @param s stream
 
55
 * @param length length
 
56
 */
 
57
 
 
58
int er_write_length(wStream* s, int length, BOOL flag)
 
59
{
 
60
        if (flag)
 
61
                return der_write_length(s, length);
 
62
        else
 
63
                return ber_write_length(s, length);
 
64
}
 
65
 
 
66
int _er_skip_length(int length)
 
67
{
 
68
        if (length > 0x7F)
 
69
                return 3;
 
70
        else
 
71
                return 1;
 
72
}
 
73
 
 
74
int er_get_content_length(int length)
 
75
{
 
76
        if (length - 1 > 0x7F)
 
77
                return length - 4;
 
78
        else
 
79
                return length - 2;
 
80
}
 
81
 
 
82
/**
 
83
 * Read er Universal tag.
 
84
 * @param s stream
 
85
 * @param tag er universally-defined tag
 
86
 * @return
 
87
 */
 
88
 
 
89
BOOL er_read_universal_tag(wStream* s, BYTE tag, BOOL pc)
 
90
{
 
91
        BYTE byte;
 
92
 
 
93
        Stream_Read_UINT8(s, byte);
 
94
 
 
95
        if (byte != (ER_CLASS_UNIV | ER_PC(pc) | (ER_TAG_MASK & tag)))
 
96
                return FALSE;
 
97
 
 
98
        return TRUE;
 
99
}
 
100
 
 
101
/**
 
102
 * Write er Universal tag.
 
103
 * @param s stream
 
104
 * @param tag er universally-defined tag
 
105
 * @param pc primitive (FALSE) or constructed (TRUE)
 
106
 */
 
107
 
 
108
void er_write_universal_tag(wStream* s, BYTE tag, BOOL pc)
 
109
{
 
110
        Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_PC(pc)) | (ER_TAG_MASK & tag));
 
111
}
 
112
 
 
113
/**
 
114
 * Read er Application tag.
 
115
 * @param s stream
 
116
 * @param tag er application-defined tag
 
117
 * @param length length
 
118
 */
 
119
 
 
120
BOOL er_read_application_tag(wStream* s, BYTE tag, int* length)
 
121
{
 
122
        BYTE byte;
 
123
 
 
124
        if (tag > 30)
 
125
        {
 
126
                Stream_Read_UINT8(s, byte);
 
127
 
 
128
                if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK))
 
129
                        return FALSE;
 
130
 
 
131
                Stream_Read_UINT8(s, byte);
 
132
 
 
133
                if (byte != tag)
 
134
                        return FALSE;
 
135
 
 
136
                er_read_length(s, length);
 
137
        }
 
138
        else
 
139
        {
 
140
                Stream_Read_UINT8(s, byte);
 
141
 
 
142
                if (byte != ((ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag)))
 
143
                        return FALSE;
 
144
 
 
145
                er_read_length(s, length);
 
146
        }
 
147
 
 
148
        return TRUE;
 
149
}
 
150
 
 
151
/**
 
152
 * Write er Application tag.
 
153
 * @param s stream
 
154
 * @param tag er application-defined tag
 
155
 * @param length length
 
156
 */
 
157
 
 
158
void er_write_application_tag(wStream* s, BYTE tag, int length, BOOL flag)
 
159
{
 
160
        if (tag > 30)
 
161
        {
 
162
                Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | ER_TAG_MASK);
 
163
                Stream_Write_UINT8(s, tag);
 
164
                er_write_length(s, length, flag);
 
165
        }
 
166
        else
 
167
        {
 
168
                Stream_Write_UINT8(s, (ER_CLASS_APPL | ER_CONSTRUCT) | (ER_TAG_MASK & tag));
 
169
                er_write_length(s, length, flag);
 
170
        }
 
171
}
 
172
 
 
173
BOOL er_read_contextual_tag(wStream* s, BYTE tag, int* length, BOOL pc)
 
174
{
 
175
        BYTE byte;
 
176
 
 
177
        Stream_Read_UINT8(s, byte);
 
178
 
 
179
        if (byte != ((ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag)))
 
180
        {
 
181
                Stream_Rewind(s, 1);
 
182
                return FALSE;
 
183
        }
 
184
 
 
185
        er_read_length(s, length);
 
186
 
 
187
        return TRUE;
 
188
}
 
189
 
 
190
int er_write_contextual_tag(wStream* s, BYTE tag, int length, BOOL pc, BOOL flag)
 
191
{
 
192
        Stream_Write_UINT8(s, (ER_CLASS_CTXT | ER_PC(pc)) | (ER_TAG_MASK & tag));
 
193
        return er_write_length(s, length, flag) + 1;
 
194
}
 
195
 
 
196
int er_skip_contextual_tag(int length)
 
197
{
 
198
        return _er_skip_length(length) + 1;
 
199
}
 
200
 
 
201
BOOL er_read_sequence_tag(wStream* s, int* length)
 
202
{
 
203
        BYTE byte;
 
204
 
 
205
        Stream_Read_UINT8(s, byte);
 
206
 
 
207
        if (byte != ((ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_SEQUENCE_OF)))
 
208
                return FALSE;
 
209
 
 
210
        er_read_length(s, length);
 
211
 
 
212
        return TRUE;
 
213
}
 
214
 
 
215
/**
 
216
 * Write er SEQUENCE tag.
 
217
 * @param s stream
 
218
 * @param length length
 
219
 */
 
220
 
 
221
int er_write_sequence_tag(wStream* s, int length, BOOL flag)
 
222
{
 
223
        Stream_Write_UINT8(s, (ER_CLASS_UNIV | ER_CONSTRUCT) | (ER_TAG_MASK & ER_TAG_SEQUENCE));
 
224
        return er_write_length(s, length, flag) + 1;
 
225
}
 
226
 
 
227
int er_skip_sequence(int length)
 
228
{
 
229
        return 1 + _er_skip_length(length) + length;
 
230
}
 
231
 
 
232
int er_skip_sequence_tag(int length)
 
233
{
 
234
        return 1 + _er_skip_length(length);
 
235
}
 
236
 
 
237
BOOL er_read_enumerated(wStream* s, BYTE* enumerated, BYTE count)
 
238
{
 
239
        int length;
 
240
 
 
241
        er_read_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
 
242
        er_read_length(s, &length);
 
243
 
 
244
        if (length == 1)
 
245
                Stream_Read_UINT8(s, *enumerated);
 
246
        else
 
247
                return FALSE;
 
248
 
 
249
        /* check that enumerated value falls within expected range */
 
250
        if (*enumerated + 1 > count)
 
251
                return FALSE;
 
252
 
 
253
        return TRUE;
 
254
}
 
255
 
 
256
void er_write_enumerated(wStream* s, BYTE enumerated, BYTE count, BOOL flag)
 
257
{
 
258
        er_write_universal_tag(s, ER_TAG_ENUMERATED, FALSE);
 
259
        er_write_length(s, 1, flag);
 
260
        Stream_Write_UINT8(s, enumerated);
 
261
}
 
262
 
 
263
BOOL er_read_bit_string(wStream* s, int* length, BYTE* padding)
 
264
{
 
265
        er_read_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
 
266
        er_read_length(s, length);
 
267
        Stream_Read_UINT8(s, *padding);
 
268
 
 
269
        return TRUE;
 
270
}
 
271
 
 
272
BOOL er_write_bit_string_tag(wStream* s, UINT32 length, BYTE padding, BOOL flag)
 
273
{
 
274
        er_write_universal_tag(s, ER_TAG_BIT_STRING, FALSE);
 
275
        er_write_length(s, length, flag);
 
276
        Stream_Write_UINT8(s, padding);
 
277
        return TRUE;
 
278
}
 
279
 
 
280
BOOL er_read_octet_string(wStream* s, int* length)
 
281
{
 
282
        if(!er_read_universal_tag(s, ER_TAG_OCTET_STRING, FALSE))
 
283
                return FALSE;
 
284
        er_read_length(s, length);
 
285
 
 
286
        return TRUE;
 
287
}
 
288
 
 
289
/**
 
290
 * Write a er OCTET_STRING
 
291
 * @param s stream
 
292
 * @param oct_str octet string
 
293
 * @param length string length
 
294
 */
 
295
 
 
296
void er_write_octet_string(wStream* s, BYTE* oct_str, int length, BOOL flag)
 
297
{
 
298
        er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
 
299
        er_write_length(s, length, flag);
 
300
        Stream_Write(s, oct_str, length);
 
301
}
 
302
 
 
303
int er_write_octet_string_tag(wStream* s, int length, BOOL flag)
 
304
{
 
305
        er_write_universal_tag(s, ER_TAG_OCTET_STRING, FALSE);
 
306
        er_write_length(s, length, flag);
 
307
        return 1 + _er_skip_length(length);
 
308
}
 
309
 
 
310
int er_skip_octet_string(int length)
 
311
{
 
312
        return 1 + _er_skip_length(length) + length;
 
313
}
 
314
 
 
315
/**
 
316
 * Read a er BOOLEAN
 
317
 * @param s
 
318
 * @param value
 
319
 */
 
320
 
 
321
BOOL er_read_BOOL(wStream* s, BOOL* value)
 
322
{
 
323
        int length;
 
324
        BYTE v;
 
325
 
 
326
        if (!er_read_universal_tag(s, ER_TAG_BOOLEAN, FALSE))
 
327
                return FALSE;
 
328
        er_read_length(s, &length);
 
329
        if (length != 1)
 
330
                return FALSE;
 
331
        Stream_Read_UINT8(s, v);
 
332
        *value = (v ? TRUE : FALSE);
 
333
        return TRUE;
 
334
}
 
335
 
 
336
/**
 
337
 * Write a er BOOLEAN
 
338
 * @param s
 
339
 * @param value
 
340
 */
 
341
 
 
342
void er_write_BOOL(wStream* s, BOOL value)
 
343
{
 
344
        er_write_universal_tag(s, ER_TAG_BOOLEAN, FALSE);
 
345
        er_write_length(s, 1, FALSE);
 
346
        Stream_Write_UINT8(s, (value == TRUE) ? 0xFF : 0);
 
347
}
 
348
 
 
349
BOOL er_read_integer(wStream* s, UINT32* value)
 
350
{
 
351
        int length;
 
352
 
 
353
        er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
 
354
        er_read_length(s, &length);
 
355
 
 
356
        if (value == NULL)
 
357
        {
 
358
                Stream_Seek(s, length);
 
359
                return TRUE;
 
360
        }
 
361
 
 
362
        if (length == 1)
 
363
        {
 
364
                Stream_Read_UINT8(s, *value);
 
365
        }
 
366
        else if (length == 2)
 
367
        {
 
368
                Stream_Read_UINT16_BE(s, *value);
 
369
        }
 
370
        else if (length == 3)
 
371
        {
 
372
                BYTE byte;
 
373
                Stream_Read_UINT8(s, byte);
 
374
                Stream_Read_UINT16_BE(s, *value);
 
375
                *value += (byte << 16);
 
376
        }
 
377
        else if (length == 4)
 
378
        {
 
379
                Stream_Read_UINT32_BE(s, *value);
 
380
        }
 
381
        else
 
382
        {
 
383
                return FALSE;
 
384
        }
 
385
 
 
386
        return TRUE;
 
387
}
 
388
 
 
389
/**
 
390
 * Write a er INTEGER
 
391
 * @param s
 
392
 * @param value
 
393
 */
 
394
 
 
395
int er_write_integer(wStream* s, INT32 value)
 
396
{
 
397
        er_write_universal_tag(s, ER_TAG_INTEGER, FALSE);
 
398
 
 
399
        if (value <= 127 && value >= -128)
 
400
        {
 
401
                er_write_length(s, 1, FALSE);
 
402
                Stream_Write_UINT8(s, value);
 
403
                return 2;
 
404
        }
 
405
        else if (value <= 32767 && value >= -32768)
 
406
        {
 
407
                er_write_length(s, 2, FALSE);
 
408
                Stream_Write_UINT16_BE(s, value);
 
409
                return 3;
 
410
        }
 
411
        else
 
412
        {
 
413
                er_write_length(s, 4, FALSE);
 
414
                Stream_Write_UINT32_BE(s, value);
 
415
                return 5;
 
416
        }
 
417
 
 
418
        return 0;
 
419
}
 
420
 
 
421
int er_skip_integer(INT32 value)
 
422
{
 
423
        if (value <= 127 && value >= -128)
 
424
        {
 
425
                return _er_skip_length(1) + 2;
 
426
        }
 
427
        else if (value <= 32767 && value >= -32768)
 
428
        {
 
429
                return _er_skip_length(2) + 3;
 
430
        }
 
431
        else
 
432
        {
 
433
                return _er_skip_length(4) + 5;
 
434
        }
 
435
 
 
436
        return 0;
 
437
}
 
438
 
 
439
BOOL er_read_integer_length(wStream* s, int* length)
 
440
{
 
441
        er_read_universal_tag(s, ER_TAG_INTEGER, FALSE);
 
442
        er_read_length(s, length);
 
443
        return TRUE;
 
444
}