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

« back to all changes in this revision

Viewing changes to libfreerdp/crypto/per.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 Packed Encoding Rules (BER)
 
4
 *
 
5
 * Copyright 2011-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * Unless required by applicable law or agreed to in writing, software
 
14
 * distributed under the License is distributed on an "AS IS" BASIS,
 
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
16
 * See the License for the specific language governing permissions and
 
17
 * limitations under the License.
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include "config.h"
 
22
#endif
 
23
 
 
24
#include <freerdp/crypto/per.h>
 
25
 
 
26
/**
 
27
 * Read PER length.
 
28
 * @param s stream
 
29
 * @param length length
 
30
 * @return
 
31
 */
 
32
 
 
33
BOOL per_read_length(wStream* s, UINT16* length)
 
34
{
 
35
        BYTE byte;
 
36
 
 
37
        if (Stream_GetRemainingLength(s) < 1)
 
38
                return FALSE;
 
39
 
 
40
        Stream_Read_UINT8(s, byte);
 
41
 
 
42
        if (byte & 0x80)
 
43
        {
 
44
                if (Stream_GetRemainingLength(s) < 1)
 
45
                        return FALSE;
 
46
 
 
47
                byte &= ~(0x80);
 
48
                *length = (byte << 8);
 
49
                Stream_Read_UINT8(s, byte);
 
50
                *length += byte;
 
51
        }
 
52
        else
 
53
        {
 
54
                *length = byte;
 
55
        }
 
56
 
 
57
        return TRUE;
 
58
}
 
59
 
 
60
/**
 
61
 * Write PER length.
 
62
 * @param s stream
 
63
 * @param length length
 
64
 */
 
65
 
 
66
void per_write_length(wStream* s, int length)
 
67
{
 
68
        if (length > 0x7F)
 
69
                Stream_Write_UINT16_BE(s, (length | 0x8000));
 
70
        else
 
71
                Stream_Write_UINT8(s, length);
 
72
}
 
73
 
 
74
/**
 
75
 * Read PER choice.
 
76
 * @param s stream
 
77
 * @param choice choice
 
78
 * @return
 
79
 */
 
80
 
 
81
BOOL per_read_choice(wStream* s, BYTE* choice)
 
82
{
 
83
        if (Stream_GetRemainingLength(s) < 1)
 
84
                return FALSE;
 
85
 
 
86
        Stream_Read_UINT8(s, *choice);
 
87
        return TRUE;
 
88
}
 
89
 
 
90
/**
 
91
 * Write PER CHOICE.
 
92
 * @param s stream
 
93
 * @param choice index of chosen field
 
94
 */
 
95
 
 
96
void per_write_choice(wStream* s, BYTE choice)
 
97
{
 
98
        Stream_Write_UINT8(s, choice);
 
99
}
 
100
 
 
101
/**
 
102
 * Read PER selection.
 
103
 * @param s stream
 
104
 * @param selection selection
 
105
 * @return
 
106
 */
 
107
 
 
108
BOOL per_read_selection(wStream* s, BYTE* selection)
 
109
{
 
110
        if (Stream_GetRemainingLength(s) < 1)
 
111
                return FALSE;
 
112
 
 
113
        Stream_Read_UINT8(s, *selection);
 
114
        return TRUE;
 
115
}
 
116
 
 
117
/**
 
118
 * Write PER selection for OPTIONAL fields.
 
119
 * @param s stream
 
120
 * @param selection bit map of selected fields
 
121
 */
 
122
 
 
123
void per_write_selection(wStream* s, BYTE selection)
 
124
{
 
125
        Stream_Write_UINT8(s, selection);
 
126
}
 
127
 
 
128
/**
 
129
 * Read PER number of sets.
 
130
 * @param s stream
 
131
 * @param number number of sets
 
132
 * @return
 
133
 */
 
134
 
 
135
BOOL per_read_number_of_sets(wStream* s, BYTE* number)
 
136
{
 
137
        if (Stream_GetRemainingLength(s) < 1)
 
138
                return FALSE;
 
139
 
 
140
        Stream_Read_UINT8(s, *number);
 
141
        return TRUE;
 
142
}
 
143
 
 
144
/**
 
145
 * Write PER number of sets for SET OF.
 
146
 * @param s stream
 
147
 * @param number number of sets
 
148
 */
 
149
 
 
150
void per_write_number_of_sets(wStream* s, BYTE number)
 
151
{
 
152
        Stream_Write_UINT8(s, number);
 
153
}
 
154
 
 
155
/**
 
156
 * Read PER padding with zeros.
 
157
 * @param s stream
 
158
 * @param length
 
159
 */
 
160
 
 
161
BOOL per_read_padding(wStream* s, int length)
 
162
{
 
163
        if (Stream_GetRemainingLength(s) < length)
 
164
                return FALSE;
 
165
 
 
166
        Stream_Seek(s, length);
 
167
        return TRUE;
 
168
}
 
169
 
 
170
/**
 
171
 * Write PER padding with zeros.
 
172
 * @param s stream
 
173
 * @param length
 
174
 */
 
175
 
 
176
void per_write_padding(wStream* s, int length)
 
177
{
 
178
        int i;
 
179
 
 
180
        for (i = 0; i < length; i++)
 
181
                Stream_Write_UINT8(s, 0);
 
182
}
 
183
 
 
184
/**
 
185
 * Read PER INTEGER.
 
186
 * @param s stream
 
187
 * @param integer integer
 
188
 * @return
 
189
 */
 
190
 
 
191
BOOL per_read_integer(wStream* s, UINT32* integer)
 
192
{
 
193
        UINT16 length;
 
194
 
 
195
        if (!per_read_length(s, &length))
 
196
                return FALSE;
 
197
 
 
198
        if (Stream_GetRemainingLength(s) < length)
 
199
                return FALSE;
 
200
 
 
201
        if (length == 1)
 
202
                Stream_Read_UINT8(s, *integer);
 
203
        else if (length == 2)
 
204
                Stream_Read_UINT16_BE(s, *integer);
 
205
        else
 
206
                return FALSE;
 
207
 
 
208
        return TRUE;
 
209
}
 
210
 
 
211
/**
 
212
 * Write PER INTEGER.
 
213
 * @param s stream
 
214
 * @param integer integer
 
215
 */
 
216
 
 
217
void per_write_integer(wStream* s, UINT32 integer)
 
218
{
 
219
        if (integer <= 0xFF)
 
220
        {
 
221
                per_write_length(s, 1);
 
222
                Stream_Write_UINT8(s, integer);
 
223
        }
 
224
        else if (integer <= 0xFFFF)
 
225
        {
 
226
                per_write_length(s, 2);
 
227
                Stream_Write_UINT16_BE(s, integer);
 
228
        }
 
229
        else if (integer <= 0xFFFFFFFF)
 
230
        {
 
231
                per_write_length(s, 4);
 
232
                Stream_Write_UINT32_BE(s, integer);
 
233
        }
 
234
}
 
235
 
 
236
/**
 
237
 * Read PER INTEGER (UINT16).
 
238
 * @param s stream
 
239
 * @param integer integer
 
240
 * @param min minimum value
 
241
 * @return
 
242
 */
 
243
 
 
244
BOOL per_read_integer16(wStream* s, UINT16* integer, UINT16 min)
 
245
{
 
246
        if (Stream_GetRemainingLength(s) < 2)
 
247
                return FALSE;
 
248
 
 
249
        Stream_Read_UINT16_BE(s, *integer);
 
250
 
 
251
        if (*integer + min > 0xFFFF)
 
252
                return FALSE;
 
253
 
 
254
        *integer += min;
 
255
 
 
256
        return TRUE;
 
257
}
 
258
 
 
259
/**
 
260
 * Write PER INTEGER (UINT16).
 
261
 * @param s stream
 
262
 * @param integer integer
 
263
 * @param min minimum value
 
264
 */
 
265
 
 
266
void per_write_integer16(wStream* s, UINT16 integer, UINT16 min)
 
267
{
 
268
        Stream_Write_UINT16_BE(s, integer - min);
 
269
}
 
270
 
 
271
/**
 
272
 * Read PER ENUMERATED.
 
273
 * @param s stream
 
274
 * @param enumerated enumerated
 
275
 * @param count enumeration count
 
276
 * @return
 
277
 */
 
278
 
 
279
BOOL per_read_enumerated(wStream* s, BYTE* enumerated, BYTE count)
 
280
{
 
281
        if (Stream_GetRemainingLength(s) < 1)
 
282
                return FALSE;
 
283
 
 
284
        Stream_Read_UINT8(s, *enumerated);
 
285
 
 
286
        /* check that enumerated value falls within expected range */
 
287
        if (*enumerated + 1 > count)
 
288
                return FALSE;
 
289
 
 
290
        return TRUE;
 
291
}
 
292
 
 
293
/**
 
294
 * Write PER ENUMERATED.
 
295
 * @param s stream
 
296
 * @param enumerated enumerated
 
297
 * @param count enumeration count
 
298
 * @return
 
299
 */
 
300
 
 
301
void per_write_enumerated(wStream* s, BYTE enumerated, BYTE count)
 
302
{
 
303
        Stream_Write_UINT8(s, enumerated);
 
304
}
 
305
 
 
306
/**
 
307
 * Read PER OBJECT_IDENTIFIER (OID).
 
308
 * @param s stream
 
309
 * @param oid object identifier (OID)
 
310
 * @return
 
311
 */
 
312
 
 
313
BOOL per_read_object_identifier(wStream* s, BYTE oid[6])
 
314
{
 
315
        BYTE t12;
 
316
        UINT16 length;
 
317
        BYTE a_oid[6];
 
318
 
 
319
        if (!per_read_length(s, &length))
 
320
                return FALSE;
 
321
 
 
322
        if (length != 5)
 
323
                return FALSE;
 
324
 
 
325
        if (Stream_GetRemainingLength(s) < length)
 
326
                return FALSE;
 
327
 
 
328
        Stream_Read_UINT8(s, t12); /* first two tuples */
 
329
        a_oid[0] = (t12 >> 4);
 
330
        a_oid[1] = (t12 & 0x0F);
 
331
 
 
332
        Stream_Read_UINT8(s, a_oid[2]); /* tuple 3 */
 
333
        Stream_Read_UINT8(s, a_oid[3]); /* tuple 4 */
 
334
        Stream_Read_UINT8(s, a_oid[4]); /* tuple 5 */
 
335
        Stream_Read_UINT8(s, a_oid[5]); /* tuple 6 */
 
336
 
 
337
        if ((a_oid[0] == oid[0]) && (a_oid[1] == oid[1]) &&
 
338
                (a_oid[2] == oid[2]) && (a_oid[3] == oid[3]) &&
 
339
                (a_oid[4] == oid[4]) && (a_oid[5] == oid[5]))
 
340
        {
 
341
                return TRUE;
 
342
        }
 
343
        else
 
344
        {
 
345
                return FALSE;
 
346
        }
 
347
}
 
348
 
 
349
/**
 
350
 * Write PER OBJECT_IDENTIFIER (OID)
 
351
 * @param s stream
 
352
 * @param oid object identifier (oid)
 
353
 */
 
354
 
 
355
void per_write_object_identifier(wStream* s, BYTE oid[6])
 
356
{
 
357
        BYTE t12 = (oid[0] << 4) & (oid[1] & 0x0F);
 
358
        Stream_Write_UINT8(s, 5); /* length */
 
359
        Stream_Write_UINT8(s, t12); /* first two tuples */
 
360
        Stream_Write_UINT8(s, oid[2]); /* tuple 3 */
 
361
        Stream_Write_UINT8(s, oid[3]); /* tuple 4 */
 
362
        Stream_Write_UINT8(s, oid[4]); /* tuple 5 */
 
363
        Stream_Write_UINT8(s, oid[5]); /* tuple 6 */
 
364
}
 
365
 
 
366
/**
 
367
 * Write PER string.
 
368
 * @param s stream
 
369
 * @param str string
 
370
 * @param length string length
 
371
 */
 
372
 
 
373
void per_write_string(wStream* s, BYTE* str, int length)
 
374
{
 
375
        int i;
 
376
 
 
377
        for (i = 0; i < length; i++)
 
378
                Stream_Write_UINT8(s, str[i]);
 
379
}
 
380
 
 
381
/**
 
382
 * Read PER OCTET_STRING.
 
383
 * @param s stream
 
384
 * @param oct_str octet string
 
385
 * @param length string length
 
386
 * @param min minimum length
 
387
 * @return
 
388
 */
 
389
 
 
390
BOOL per_read_octet_string(wStream* s, BYTE* oct_str, int length, int min)
 
391
{
 
392
        int i;
 
393
        UINT16 mlength;
 
394
        BYTE* a_oct_str;
 
395
 
 
396
        if (!per_read_length(s, &mlength))
 
397
                return FALSE;
 
398
 
 
399
        if (mlength + min != length)
 
400
                return FALSE;
 
401
 
 
402
        if (Stream_GetRemainingLength(s) < length)
 
403
                return FALSE;
 
404
 
 
405
        a_oct_str = Stream_Pointer(s);
 
406
        Stream_Seek(s, length);
 
407
 
 
408
        for (i = 0; i < length; i++)
 
409
        {
 
410
                if (a_oct_str[i] != oct_str[i])
 
411
                        return FALSE;
 
412
        }
 
413
 
 
414
        return TRUE;
 
415
}
 
416
 
 
417
/**
 
418
 * Write PER OCTET_STRING
 
419
 * @param s stream
 
420
 * @param oct_str octet string
 
421
 * @param length string length
 
422
 * @param min minimum string length
 
423
 */
 
424
 
 
425
void per_write_octet_string(wStream* s, BYTE* oct_str, int length, int min)
 
426
{
 
427
        int i;
 
428
        int mlength;
 
429
 
 
430
        mlength = (length - min >= 0) ? length - min : min;
 
431
 
 
432
        per_write_length(s, mlength);
 
433
 
 
434
        for (i = 0; i < length; i++)
 
435
                Stream_Write_UINT8(s, oct_str[i]);
 
436
}
 
437
 
 
438
/**
 
439
 * Read PER NumericString.
 
440
 * @param s stream
 
441
 * @param num_str numeric string
 
442
 * @param length string length
 
443
 * @param min minimum string length
 
444
 */
 
445
 
 
446
BOOL per_read_numeric_string(wStream* s, int min)
 
447
{
 
448
        int length;
 
449
        UINT16 mlength;
 
450
 
 
451
        if (!per_read_length(s, &mlength))
 
452
                return FALSE;
 
453
 
 
454
        length = (mlength + min + 1) / 2;
 
455
 
 
456
        if (Stream_GetRemainingLength(s) < length)
 
457
                return FALSE;
 
458
 
 
459
        Stream_Seek(s, length);
 
460
        return TRUE;
 
461
}
 
462
 
 
463
/**
 
464
 * Write PER NumericString.
 
465
 * @param s stream
 
466
 * @param num_str numeric string
 
467
 * @param length string length
 
468
 * @param min minimum string length
 
469
 */
 
470
 
 
471
void per_write_numeric_string(wStream* s, BYTE* num_str, int length, int min)
 
472
{
 
473
        int i;
 
474
        int mlength;
 
475
        BYTE num, c1, c2;
 
476
 
 
477
        mlength = (length - min >= 0) ? length - min : min;
 
478
 
 
479
        per_write_length(s, mlength);
 
480
 
 
481
        for (i = 0; i < length; i += 2)
 
482
        {
 
483
                c1 = num_str[i];
 
484
                c2 = ((i + 1) < length) ? num_str[i + 1] : 0x30;
 
485
 
 
486
                c1 = (c1 - 0x30) % 10;
 
487
                c2 = (c2 - 0x30) % 10;
 
488
                num = (c1 << 4) | c2;
 
489
 
 
490
                Stream_Write_UINT8(s, num); /* string */
 
491
        }
 
492
}