Coverage Report

Created: 2024-02-25 07:20

/src/libscca/libfwnt/libfwnt_security_identifier.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Windows NT Security Identifier (SID) functions
3
 *
4
 * Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfwnt_definitions.h"
28
#include "libfwnt_libcerror.h"
29
#include "libfwnt_security_identifier.h"
30
#include "libfwnt_types.h"
31
32
/* Creates a security identifier
33
 * Make sure the value security_identifier is referencing, is set to NULL
34
 * Returns 1 if successful or -1 on error
35
 */
36
int libfwnt_security_identifier_initialize(
37
     libfwnt_security_identifier_t **security_identifier,
38
     libcerror_error_t **error )
39
26.2k
{
40
26.2k
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
41
26.2k
  static char *function                                                = "libfwnt_security_identifier_initialize";
42
43
26.2k
  if( security_identifier == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid security identifier.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
26.2k
  if( *security_identifier != NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
59
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60
0
     "%s: invalid security identifier value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
26.2k
  internal_security_identifier = memory_allocate_structure(
66
26.2k
                                  libfwnt_internal_security_identifier_t );
67
68
26.2k
  if( internal_security_identifier == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
73
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74
0
     "%s: unable to create security identifier.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
26.2k
  if( memory_set(
80
26.2k
       internal_security_identifier,
81
26.2k
       0,
82
26.2k
       sizeof( libfwnt_internal_security_identifier_t ) ) == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
88
0
     "%s: unable to clear security identifier.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
26.2k
  *security_identifier = (libfwnt_security_identifier_t *) internal_security_identifier;
94
95
26.2k
  return( 1 );
96
97
0
on_error:
98
0
  if( internal_security_identifier != NULL )
99
0
  {
100
0
    memory_free(
101
0
     internal_security_identifier );
102
0
  }
103
0
  return( -1 );
104
26.2k
}
105
106
/* Frees a security identifier
107
 * Returns 1 if successful or -1 on error
108
 */
109
int libfwnt_security_identifier_free(
110
     libfwnt_security_identifier_t **security_identifier,
111
     libcerror_error_t **error )
112
21.4k
{
113
21.4k
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
114
21.4k
  static char *function                                                = "libfwnt_security_identifier_free";
115
21.4k
  int result                                                           = 1;
116
117
21.4k
  if( security_identifier == NULL )
118
0
  {
119
0
    libcerror_error_set(
120
0
     error,
121
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123
0
     "%s: invalid security identifier.",
124
0
     function );
125
126
0
    return( -1 );
127
0
  }
128
21.4k
  if( *security_identifier != NULL )
129
21.4k
  {
130
21.4k
    internal_security_identifier = (libfwnt_internal_security_identifier_t *) *security_identifier;
131
132
21.4k
    if( internal_security_identifier->is_managed == 0 )
133
21.4k
    {
134
21.4k
      if( libfwnt_internal_security_identifier_free(
135
21.4k
           &internal_security_identifier,
136
21.4k
           error ) != 1 )
137
0
      {
138
0
        libcerror_error_set(
139
0
         error,
140
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
141
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
142
0
         "%s: unable to free security identifier.",
143
0
         function );
144
145
0
        result = -1;
146
0
      }
147
21.4k
    }
148
21.4k
    *security_identifier = NULL;
149
21.4k
  }
150
21.4k
  return( result );
151
21.4k
}
152
153
/* Frees a security identifier
154
 * Returns 1 if successful or -1 on error
155
 */
156
int libfwnt_internal_security_identifier_free(
157
     libfwnt_internal_security_identifier_t **internal_security_identifier,
158
     libcerror_error_t **error )
159
26.2k
{
160
26.2k
  static char *function = "libfwnt_internal_security_identifier_free";
161
162
26.2k
  if( internal_security_identifier == NULL )
163
0
  {
164
0
    libcerror_error_set(
165
0
     error,
166
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
167
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
168
0
     "%s: invalid security identifier.",
169
0
     function );
170
171
0
    return( -1 );
172
0
  }
173
26.2k
  if( *internal_security_identifier != NULL )
174
26.2k
  {
175
26.2k
    memory_free(
176
26.2k
     *internal_security_identifier );
177
178
26.2k
    *internal_security_identifier = NULL;
179
26.2k
  }
180
26.2k
  return( 1 );
181
26.2k
}
182
183
/* Converts a security identifier stored in a byte stream into a runtime version
184
 * Returns 1 if successful or -1 on error
185
 */
186
int libfwnt_security_identifier_copy_from_byte_stream(
187
     libfwnt_security_identifier_t *security_identifier,
188
     const uint8_t *byte_stream,
189
     size_t byte_stream_size,
190
     int byte_order,
191
     libcerror_error_t **error )
192
26.2k
{
193
26.2k
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
194
26.2k
  static char *function                                                = "libfwnt_security_identifier_copy_from_byte_stream";
195
26.2k
  size_t security_identifier_size                                      = 0;
196
26.2k
  uint8_t sub_authority_index                                          = 0;
197
198
26.2k
  if( security_identifier == NULL )
199
0
  {
200
0
    libcerror_error_set(
201
0
     error,
202
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
203
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
204
0
     "%s: invalid security identifier.",
205
0
     function );
206
207
0
    return( -1 );
208
0
  }
209
26.2k
  internal_security_identifier = (libfwnt_internal_security_identifier_t *) security_identifier;
210
211
26.2k
  if( byte_stream == NULL )
212
0
  {
213
0
    libcerror_error_set(
214
0
     error,
215
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
216
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
217
0
     "%s: invalid byte stream.",
218
0
     function );
219
220
0
    return( -1 );
221
0
  }
222
26.2k
  if( byte_stream_size < 8 )
223
1.19k
  {
224
1.19k
    libcerror_error_set(
225
1.19k
     error,
226
1.19k
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
227
1.19k
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
228
1.19k
     "%s: byte stream too small.",
229
1.19k
     function );
230
231
1.19k
    return( -1 );
232
1.19k
  }
233
25.0k
  if( byte_stream_size > (size_t) SSIZE_MAX )
234
0
  {
235
0
    libcerror_error_set(
236
0
     error,
237
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
238
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
239
0
     "%s: byte stream size exceeds maximum.",
240
0
     function );
241
242
0
    return( -1 );
243
0
  }
244
25.0k
  if( byte_order != LIBFWNT_ENDIAN_LITTLE )
245
0
  {
246
0
    libcerror_error_set(
247
0
     error,
248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
249
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
250
0
     "%s: unsupported byte order.",
251
0
     function );
252
253
0
    return( -1 );
254
0
  }
255
25.0k
  internal_security_identifier->revision_number           = byte_stream[ 0 ];
256
25.0k
  internal_security_identifier->number_of_sub_authorities = byte_stream[ 1 ];
257
258
25.0k
  if( internal_security_identifier->number_of_sub_authorities > 15 )
259
2.56k
  {
260
2.56k
    libcerror_error_set(
261
2.56k
     error,
262
2.56k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
2.56k
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
264
2.56k
     "%s: unsupported security identifier contains more than 15 sub authoritites.",
265
2.56k
     function );
266
267
2.56k
    return( -1 );
268
2.56k
  }
269
22.4k
  security_identifier_size = 8 + ( (size_t) internal_security_identifier->number_of_sub_authorities * 4 );
270
271
22.4k
  if( (size_t) security_identifier_size > byte_stream_size )
272
1.38k
  {
273
1.38k
    libcerror_error_set(
274
1.38k
     error,
275
1.38k
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
276
1.38k
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
277
1.38k
     "%s: byte stream too small.",
278
1.38k
     function );
279
280
1.38k
    return( -1 );
281
1.38k
  }
282
21.0k
  byte_stream += 2;
283
284
  /* The authority is stored as a 48-bit value
285
   */
286
21.0k
  byte_stream_copy_to_uint48_big_endian(
287
21.0k
   byte_stream,
288
21.0k
   internal_security_identifier->authority );
289
290
21.0k
  byte_stream += 6;
291
292
21.0k
  for( sub_authority_index = 0;
293
62.0k
       sub_authority_index < internal_security_identifier->number_of_sub_authorities;
294
40.9k
       sub_authority_index++ )
295
40.9k
  {
296
40.9k
    byte_stream_copy_to_uint32_little_endian(
297
40.9k
     byte_stream,
298
40.9k
     internal_security_identifier->sub_authority[ sub_authority_index ] );
299
300
40.9k
    byte_stream += 4;
301
40.9k
  }
302
21.0k
  return( 1 );
303
22.4k
}
304
305
/* Deterimes the size of the string for the security identifier
306
 * The string size includes the end of string character
307
 * Returns 1 if successful or -1 on error
308
 */
309
int libfwnt_security_identifier_get_string_size(
310
     libfwnt_security_identifier_t *security_identifier,
311
     size_t *string_size,
312
     uint32_t string_format_flags,
313
     libcerror_error_t **error )
314
0
{
315
0
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
316
0
  static char *function                                                = "libfwnt_security_identifier_get_string_size";
317
0
  size_t value_string_index                                            = 0;
318
0
  uint64_t value_64bit                                                 = 0;
319
0
  uint8_t sub_authority_index                                          = 0;
320
321
0
  if( security_identifier == NULL )
322
0
  {
323
0
    libcerror_error_set(
324
0
     error,
325
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
326
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
327
0
     "%s: invalid security identifier.",
328
0
     function );
329
330
0
    return( -1 );
331
0
  }
332
0
  internal_security_identifier = (libfwnt_internal_security_identifier_t *) security_identifier;
333
334
0
  if( string_size == NULL )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
339
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
340
0
     "%s: invalid string size.",
341
0
     function );
342
343
0
    return( -1 );
344
0
  }
345
0
  if( string_format_flags != 0 )
346
0
  {
347
0
    libcerror_error_set(
348
0
     error,
349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
351
0
     "%s: unsupported string format flags.",
352
0
     function );
353
354
0
    return( -1 );
355
0
  }
356
0
  value_string_index = 2;
357
358
0
  value_64bit = internal_security_identifier->revision_number;
359
360
0
  do
361
0
  {
362
0
    value_string_index++;
363
364
0
    value_64bit /= 10;
365
0
  }
366
0
  while( value_64bit > 0 );
367
368
0
  value_string_index++;
369
370
0
  value_64bit = internal_security_identifier->authority;
371
372
0
  do
373
0
  {
374
0
    value_string_index++;
375
376
0
    value_64bit /= 10;
377
0
  }
378
0
  while( value_64bit > 0 );
379
380
0
  for( sub_authority_index = 0;
381
0
       sub_authority_index < internal_security_identifier->number_of_sub_authorities;
382
0
       sub_authority_index++ )
383
0
  {
384
0
    value_string_index++;
385
386
0
    value_64bit = internal_security_identifier->sub_authority[ sub_authority_index ];
387
388
0
    do
389
0
    {
390
0
      value_string_index++;
391
392
0
      value_64bit /= 10;
393
0
    }
394
0
    while( value_64bit > 0 );
395
0
  }
396
0
  value_string_index++;
397
398
0
  *string_size = value_string_index;
399
400
0
  return( 1 );
401
0
}
402
403
/* Converts the security identifier into an UTF-8 string
404
 * The string size should include the end of string character
405
 * Returns 1 if successful or -1 on error
406
 */
407
int libfwnt_security_identifier_copy_to_utf8_string(
408
     libfwnt_security_identifier_t *security_identifier,
409
     uint8_t *utf8_string,
410
     size_t utf8_string_size,
411
     uint32_t string_format_flags,
412
     libcerror_error_t **error )
413
0
{
414
0
  static char *function    = "libfwnt_security_identifier_copy_to_utf8_string";
415
0
  size_t utf8_string_index = 0;
416
417
0
  if( libfwnt_security_identifier_copy_to_utf8_string_with_index(
418
0
       security_identifier,
419
0
       utf8_string,
420
0
       utf8_string_size,
421
0
       &utf8_string_index,
422
0
       string_format_flags,
423
0
       error ) != 1 )
424
0
  {
425
0
    libcerror_error_set(
426
0
     error,
427
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
428
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
429
0
     "%s: unable to copy security identifier to UTF-8 string.",
430
0
     function );
431
432
0
    return( -1 );
433
0
  }
434
0
  return( 1 );
435
0
}
436
437
/* Converts the security identifier into an UTF-8 string
438
 * The string size should include the end of string character
439
 * Returns 1 if successful or -1 on error
440
 */
441
int libfwnt_security_identifier_copy_to_utf8_string_with_index(
442
     libfwnt_security_identifier_t *security_identifier,
443
     uint8_t *utf8_string,
444
     size_t utf8_string_size,
445
     size_t *utf8_string_index,
446
     uint32_t string_format_flags,
447
     libcerror_error_t **error )
448
0
{
449
0
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
450
0
  static char *function                                                = "libfwnt_security_identifier_copy_to_utf8_string";
451
0
  size_t string_index                                                  = 0;
452
0
  size_t value_string_index                                            = 0;
453
0
  size_t value_string_length                                           = 0;
454
0
  uint64_t value_64bit                                                 = 0;
455
0
  uint8_t sub_authority_index                                          = 0;
456
457
0
  if( security_identifier == NULL )
458
0
  {
459
0
    libcerror_error_set(
460
0
     error,
461
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
462
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
463
0
     "%s: invalid security identifier.",
464
0
     function );
465
466
0
    return( -1 );
467
0
  }
468
0
  internal_security_identifier = (libfwnt_internal_security_identifier_t *) security_identifier;
469
470
0
  if( utf8_string == NULL )
471
0
  {
472
0
    libcerror_error_set(
473
0
     error,
474
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
475
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
476
0
     "%s: invalid UTF-8 size.",
477
0
     function );
478
479
0
    return( -1 );
480
0
  }
481
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
482
0
  {
483
0
    libcerror_error_set(
484
0
     error,
485
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
486
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
487
0
     "%s: UTF-8 string size exceeds maximum.",
488
0
     function );
489
490
0
    return( -1 );
491
0
  }
492
0
  if( utf8_string_index == NULL )
493
0
  {
494
0
    libcerror_error_set(
495
0
     error,
496
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
497
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
498
0
     "%s: invalid UTF-8 string index.",
499
0
     function );
500
501
0
    return( -1 );
502
0
  }
503
0
  if( string_format_flags != 0 )
504
0
  {
505
0
    libcerror_error_set(
506
0
     error,
507
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
508
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
509
0
     "%s: unsupported string format flags.",
510
0
     function );
511
512
0
    return( -1 );
513
0
  }
514
0
  string_index = *utf8_string_index;
515
516
0
  if( ( string_index + 2 ) >= utf8_string_size )
517
0
  {
518
0
    libcerror_error_set(
519
0
     error,
520
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
521
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
522
0
     "%s: UTF-8 string is too small.",
523
0
     function );
524
525
0
    return( -1 );
526
0
  }
527
0
  utf8_string[ string_index++ ] = (uint8_t) 'S';
528
0
  utf8_string[ string_index++ ] = (uint8_t) '-';
529
530
0
  value_64bit         = internal_security_identifier->revision_number;
531
0
  value_string_length = 0;
532
533
0
  do
534
0
  {
535
0
    value_string_length++;
536
537
0
    value_64bit /= 10;
538
0
  }
539
0
  while( value_64bit > 0 );
540
541
0
  if( ( string_index + value_string_length + 1 ) >= utf8_string_size )
542
0
  {
543
0
    libcerror_error_set(
544
0
     error,
545
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
546
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
547
0
     "%s: UTF-8 string is too small.",
548
0
     function );
549
550
0
    return( -1 );
551
0
  }
552
0
  value_64bit        = internal_security_identifier->revision_number;
553
0
  value_string_index = value_string_length;
554
555
0
  while( value_string_index > 0 )
556
0
  {
557
0
    value_string_index--;
558
559
0
    utf8_string[ string_index + value_string_index ] = (uint8_t) '0' + (uint8_t) ( value_64bit % 10 );
560
561
0
    value_64bit /= 10;
562
0
  }
563
0
  string_index += value_string_length;
564
565
0
  utf8_string[ string_index++ ] = (uint8_t) '-';
566
567
0
  value_64bit         = internal_security_identifier->authority;
568
0
  value_string_length = 0;
569
570
0
  do
571
0
  {
572
0
    value_string_length++;
573
574
0
    value_64bit /= 10;
575
0
  }
576
0
  while( value_64bit > 0 );
577
578
0
  if( ( string_index + value_string_length ) >= utf8_string_size )
579
0
  {
580
0
    libcerror_error_set(
581
0
     error,
582
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
583
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
584
0
     "%s: UTF-8 string is too small.",
585
0
     function );
586
587
0
    return( -1 );
588
0
  }
589
0
  value_64bit        = internal_security_identifier->authority;
590
0
  value_string_index = value_string_length;
591
592
0
  while( value_string_index > 0 )
593
0
  {
594
0
    value_string_index--;
595
596
0
    utf8_string[ string_index + value_string_index ] = (uint8_t) '0' + (uint8_t) ( value_64bit % 10 );
597
598
0
    value_64bit /= 10;
599
0
  }
600
0
  string_index += value_string_length;
601
602
0
  for( sub_authority_index = 0;
603
0
       sub_authority_index < internal_security_identifier->number_of_sub_authorities;
604
0
       sub_authority_index++ )
605
0
  {
606
0
    value_64bit         = internal_security_identifier->sub_authority[ sub_authority_index ];
607
0
    value_string_length = 0;
608
609
0
    do
610
0
    {
611
0
      value_string_length++;
612
613
0
      value_64bit /= 10;
614
0
    }
615
0
    while( value_64bit > 0 );
616
617
0
    if( ( string_index + value_string_length + 1 ) >= utf8_string_size )
618
0
    {
619
0
      libcerror_error_set(
620
0
       error,
621
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
622
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
623
0
       "%s: UTF-8 string is too small.",
624
0
       function );
625
626
0
      return( -1 );
627
0
    }
628
0
    utf8_string[ string_index++ ] = (uint8_t) '-';
629
630
0
    value_64bit        = internal_security_identifier->sub_authority[ sub_authority_index ];
631
0
    value_string_index = value_string_length;
632
633
0
    while( value_string_index > 0 )
634
0
    {
635
0
      value_string_index--;
636
637
0
      utf8_string[ string_index + value_string_index ] = (uint8_t) '0' + (uint8_t) ( value_64bit % 10 );
638
639
0
      value_64bit /= 10;
640
0
    }
641
0
    string_index += value_string_length;
642
0
  }
643
0
  if( string_index >= utf8_string_size )
644
0
  {
645
0
    libcerror_error_set(
646
0
     error,
647
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
648
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
649
0
     "%s: UTF-8 string is too small.",
650
0
     function );
651
652
0
    return( -1 );
653
0
  }
654
0
  utf8_string[ string_index++ ] = 0;
655
656
0
  *utf8_string_index = string_index;
657
658
0
  return( 1 );
659
0
}
660
661
/* Converts the security identifier into an UTF-16 string
662
 * The string size should include the end of string character
663
 * Returns 1 if successful or -1 on error
664
 */
665
int libfwnt_security_identifier_copy_to_utf16_string(
666
     libfwnt_security_identifier_t *security_identifier,
667
     uint16_t *utf16_string,
668
     size_t utf16_string_size,
669
     uint32_t string_format_flags,
670
     libcerror_error_t **error )
671
0
{
672
0
  static char *function    = "libfwnt_security_identifier_copy_to_utf16_string";
673
0
  size_t utf16_string_index = 0;
674
675
0
  if( libfwnt_security_identifier_copy_to_utf16_string_with_index(
676
0
       security_identifier,
677
0
       utf16_string,
678
0
       utf16_string_size,
679
0
       &utf16_string_index,
680
0
       string_format_flags,
681
0
       error ) != 1 )
682
0
  {
683
0
    libcerror_error_set(
684
0
     error,
685
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
686
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
687
0
     "%s: unable to copy security identifier to UTF-16 string.",
688
0
     function );
689
690
0
    return( -1 );
691
0
  }
692
0
  return( 1 );
693
0
}
694
695
/* Converts the security identifier into an UTF-16 string
696
 * The string size should include the end of string character
697
 * Returns 1 if successful or -1 on error
698
 */
699
int libfwnt_security_identifier_copy_to_utf16_string_with_index(
700
     libfwnt_security_identifier_t *security_identifier,
701
     uint16_t *utf16_string,
702
     size_t utf16_string_size,
703
     size_t *utf16_string_index,
704
     uint32_t string_format_flags,
705
     libcerror_error_t **error )
706
0
{
707
0
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
708
0
  static char *function                                                = "libfwnt_security_identifier_copy_to_utf16_string";
709
0
  size_t string_index                                                  = 0;
710
0
  size_t value_string_index                                            = 0;
711
0
  size_t value_string_length                                           = 0;
712
0
  uint64_t value_64bit                                                 = 0;
713
0
  uint8_t sub_authority_index                                          = 0;
714
715
0
  if( security_identifier == NULL )
716
0
  {
717
0
    libcerror_error_set(
718
0
     error,
719
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
720
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
721
0
     "%s: invalid security identifier.",
722
0
     function );
723
724
0
    return( -1 );
725
0
  }
726
0
  internal_security_identifier = (libfwnt_internal_security_identifier_t *) security_identifier;
727
728
0
  if( utf16_string == NULL )
729
0
  {
730
0
    libcerror_error_set(
731
0
     error,
732
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
733
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
734
0
     "%s: invalid UTF-16 string.",
735
0
     function );
736
737
0
    return( -1 );
738
0
  }
739
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
740
0
  {
741
0
    libcerror_error_set(
742
0
     error,
743
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
744
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
745
0
     "%s: UTF-16 string size exceeds maximum.",
746
0
     function );
747
748
0
    return( -1 );
749
0
  }
750
0
  if( utf16_string_index == NULL )
751
0
  {
752
0
    libcerror_error_set(
753
0
     error,
754
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
755
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
756
0
     "%s: invalid UTF-16 string index.",
757
0
     function );
758
759
0
    return( -1 );
760
0
  }
761
0
  if( string_format_flags != 0 )
762
0
  {
763
0
    libcerror_error_set(
764
0
     error,
765
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
766
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
767
0
     "%s: unsupported string format flags.",
768
0
     function );
769
770
0
    return( -1 );
771
0
  }
772
0
  string_index = *utf16_string_index;
773
774
0
  if( ( string_index + 2 ) >= utf16_string_size )
775
0
  {
776
0
    libcerror_error_set(
777
0
     error,
778
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
779
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
780
0
     "%s: UTF-16 string is too small.",
781
0
     function );
782
783
0
    return( -1 );
784
0
  }
785
0
  utf16_string[ string_index++ ] = (uint16_t) 'S';
786
0
  utf16_string[ string_index++ ] = (uint16_t) '-';
787
788
0
  value_64bit         = internal_security_identifier->revision_number;
789
0
  value_string_length = 0;
790
791
0
  do
792
0
  {
793
0
    value_string_length++;
794
795
0
    value_64bit /= 10;
796
0
  }
797
0
  while( value_64bit > 0 );
798
799
0
  if( ( string_index + value_string_length + 1 ) >= utf16_string_size )
800
0
  {
801
0
    libcerror_error_set(
802
0
     error,
803
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
804
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
805
0
     "%s: UTF-16 string is too small.",
806
0
     function );
807
808
0
    return( -1 );
809
0
  }
810
0
  value_64bit        = internal_security_identifier->revision_number;
811
0
  value_string_index = value_string_length;
812
813
0
  while( value_string_index > 0 )
814
0
  {
815
0
    value_string_index--;
816
817
0
    utf16_string[ string_index + value_string_index ] = (uint16_t) '0' + (uint16_t) ( value_64bit % 10 );
818
819
0
    value_64bit /= 10;
820
0
  }
821
0
  string_index += value_string_length;
822
823
0
  utf16_string[ string_index++ ] = (uint16_t) '-';
824
825
0
  value_64bit         = internal_security_identifier->authority;
826
0
  value_string_length = 0;
827
828
0
  do
829
0
  {
830
0
    value_string_length++;
831
832
0
    value_64bit /= 10;
833
0
  }
834
0
  while( value_64bit > 0 );
835
836
0
  if( ( string_index + value_string_length ) >= utf16_string_size )
837
0
  {
838
0
    libcerror_error_set(
839
0
     error,
840
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
841
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
842
0
     "%s: UTF-16 string is too small.",
843
0
     function );
844
845
0
    return( -1 );
846
0
  }
847
0
  value_64bit        = internal_security_identifier->authority;
848
0
  value_string_index = value_string_length;
849
850
0
  while( value_string_index > 0 )
851
0
  {
852
0
    value_string_index--;
853
854
0
    utf16_string[ string_index + value_string_index ] = (uint16_t) '0' + (uint16_t) ( value_64bit % 10 );
855
856
0
    value_64bit /= 10;
857
0
  }
858
0
  string_index += value_string_length;
859
860
0
  for( sub_authority_index = 0;
861
0
       sub_authority_index < internal_security_identifier->number_of_sub_authorities;
862
0
       sub_authority_index++ )
863
0
  {
864
0
    value_64bit         = internal_security_identifier->sub_authority[ sub_authority_index ];
865
0
    value_string_length = 0;
866
867
0
    do
868
0
    {
869
0
      value_64bit /= 10;
870
871
0
      value_string_length++;
872
0
    }
873
0
    while( value_64bit > 0 );
874
875
0
    if( ( string_index + value_string_length + 1 ) >= utf16_string_size )
876
0
    {
877
0
      libcerror_error_set(
878
0
       error,
879
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
880
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
881
0
       "%s: UTF-16 string is too small.",
882
0
       function );
883
884
0
      return( -1 );
885
0
    }
886
0
    utf16_string[ string_index++ ] = (uint16_t) '-';
887
888
0
    value_64bit        = internal_security_identifier->sub_authority[ sub_authority_index ];
889
0
    value_string_index = value_string_length;
890
891
0
    while( value_string_index > 0 )
892
0
    {
893
0
      value_string_index--;
894
895
0
      utf16_string[ string_index + value_string_index ] = (uint16_t) '0' + (uint16_t) ( value_64bit % 10 );
896
897
0
      value_64bit /= 10;
898
0
    }
899
0
    string_index += value_string_length;
900
0
  }
901
0
  if( string_index >= utf16_string_size )
902
0
  {
903
0
    libcerror_error_set(
904
0
     error,
905
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
906
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
907
0
     "%s: UTF-16 string is too small.",
908
0
     function );
909
910
0
    return( -1 );
911
0
  }
912
0
  utf16_string[ string_index++ ] = 0;
913
914
0
  *utf16_string_index = string_index;
915
916
0
  return( 1 );
917
0
}
918
919
/* Converts the security identifier into an UTF-32 string
920
 * The string size should include the end of string character
921
 * Returns 1 if successful or -1 on error
922
 */
923
int libfwnt_security_identifier_copy_to_utf32_string(
924
     libfwnt_security_identifier_t *security_identifier,
925
     uint32_t *utf32_string,
926
     size_t utf32_string_size,
927
     uint32_t string_format_flags,
928
     libcerror_error_t **error )
929
0
{
930
0
  static char *function    = "libfwnt_security_identifier_copy_to_utf32_string";
931
0
  size_t utf32_string_index = 0;
932
933
0
  if( libfwnt_security_identifier_copy_to_utf32_string_with_index(
934
0
       security_identifier,
935
0
       utf32_string,
936
0
       utf32_string_size,
937
0
       &utf32_string_index,
938
0
       string_format_flags,
939
0
       error ) != 1 )
940
0
  {
941
0
    libcerror_error_set(
942
0
     error,
943
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
944
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
945
0
     "%s: unable to copy security identifier to UTF-32 string.",
946
0
     function );
947
948
0
    return( -1 );
949
0
  }
950
0
  return( 1 );
951
0
}
952
953
/* Converts the security identifier into an UTF-32 string
954
 * The string size should include the end of string character
955
 * Returns 1 if successful or -1 on error
956
 */
957
int libfwnt_security_identifier_copy_to_utf32_string_with_index(
958
     libfwnt_security_identifier_t *security_identifier,
959
     uint32_t *utf32_string,
960
     size_t utf32_string_size,
961
     size_t *utf32_string_index,
962
     uint32_t string_format_flags,
963
     libcerror_error_t **error )
964
0
{
965
0
  libfwnt_internal_security_identifier_t *internal_security_identifier = NULL;
966
0
  static char *function                                                = "libfwnt_security_identifier_copy_to_utf32_string_with_index";
967
0
  size_t string_index                                                  = 0;
968
0
  size_t value_string_index                                            = 0;
969
0
  size_t value_string_length                                           = 0;
970
0
  uint64_t value_64bit                                                 = 0;
971
0
  uint8_t sub_authority_index                                          = 0;
972
973
0
  if( security_identifier == NULL )
974
0
  {
975
0
    libcerror_error_set(
976
0
     error,
977
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
978
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
979
0
     "%s: invalid security identifier.",
980
0
     function );
981
982
0
    return( -1 );
983
0
  }
984
0
  internal_security_identifier = (libfwnt_internal_security_identifier_t *) security_identifier;
985
986
0
  if( utf32_string == NULL )
987
0
  {
988
0
    libcerror_error_set(
989
0
     error,
990
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
991
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
992
0
     "%s: invalid UTF-32 string.",
993
0
     function );
994
995
0
    return( -1 );
996
0
  }
997
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
998
0
  {
999
0
    libcerror_error_set(
1000
0
     error,
1001
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1002
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1003
0
     "%s: UTF-32 string size exceeds maximum.",
1004
0
     function );
1005
1006
0
    return( -1 );
1007
0
  }
1008
0
  if( utf32_string_index == NULL )
1009
0
  {
1010
0
    libcerror_error_set(
1011
0
     error,
1012
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1013
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1014
0
     "%s: invalid UTF-32 string index.",
1015
0
     function );
1016
1017
0
    return( -1 );
1018
0
  }
1019
0
  if( string_format_flags != 0 )
1020
0
  {
1021
0
    libcerror_error_set(
1022
0
     error,
1023
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1024
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1025
0
     "%s: unsupported string format flags.",
1026
0
     function );
1027
1028
0
    return( -1 );
1029
0
  }
1030
0
  string_index = *utf32_string_index;
1031
1032
0
  if( ( string_index + 2 ) > utf32_string_size )
1033
0
  {
1034
0
    libcerror_error_set(
1035
0
     error,
1036
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1037
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1038
0
     "%s: UTF-32 string is too small.",
1039
0
     function );
1040
1041
0
    return( -1 );
1042
0
  }
1043
0
  utf32_string[ string_index++ ] = (uint32_t) 'S';
1044
0
  utf32_string[ string_index++ ] = (uint32_t) '-';
1045
1046
0
  value_64bit         = internal_security_identifier->revision_number;
1047
0
  value_string_length = 0;
1048
1049
0
  do
1050
0
  {
1051
0
    value_64bit /= 10;
1052
1053
0
    value_string_length++;
1054
0
  }
1055
0
  while( value_64bit > 0 );
1056
1057
0
  if( ( string_index + value_string_length + 1 ) >= utf32_string_size )
1058
0
  {
1059
0
    libcerror_error_set(
1060
0
     error,
1061
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1062
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1063
0
     "%s: UTF-32 string is too small.",
1064
0
     function );
1065
1066
0
    return( -1 );
1067
0
  }
1068
0
  value_64bit        = internal_security_identifier->revision_number;
1069
0
  value_string_index = value_string_length;
1070
1071
0
  while( value_string_index > 0 )
1072
0
  {
1073
0
    value_string_index--;
1074
1075
0
    utf32_string[ string_index + value_string_index ] = (uint32_t) '0' + (uint32_t) ( value_64bit % 10 );
1076
1077
0
    value_64bit /= 10;
1078
0
  }
1079
0
  string_index += value_string_length;
1080
1081
0
  utf32_string[ string_index++ ] = (uint32_t) '-';
1082
1083
0
  value_64bit         = internal_security_identifier->authority;
1084
0
  value_string_length = 0;
1085
1086
0
  do
1087
0
  {
1088
0
    value_string_length++;
1089
1090
0
    value_64bit /= 10;
1091
0
  }
1092
0
  while( value_64bit > 0 );
1093
1094
0
  if( ( string_index + value_string_length ) >= utf32_string_size )
1095
0
  {
1096
0
    libcerror_error_set(
1097
0
     error,
1098
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1099
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1100
0
     "%s: UTF-32 string is too small.",
1101
0
     function );
1102
1103
0
    return( -1 );
1104
0
  }
1105
0
  value_64bit        = internal_security_identifier->authority;
1106
0
  value_string_index = value_string_length;
1107
1108
0
  while( value_string_index > 0 )
1109
0
  {
1110
0
    value_string_index--;
1111
1112
0
    utf32_string[ string_index + value_string_index ] = (uint32_t) '0' + (uint32_t) ( value_64bit % 10 );
1113
1114
0
    value_64bit /= 10;
1115
0
  }
1116
0
  string_index += value_string_length;
1117
1118
0
  for( sub_authority_index = 0;
1119
0
       sub_authority_index < internal_security_identifier->number_of_sub_authorities;
1120
0
       sub_authority_index++ )
1121
0
  {
1122
0
    value_64bit         = internal_security_identifier->sub_authority[ sub_authority_index ];
1123
0
    value_string_length = 0;
1124
1125
0
    do
1126
0
    {
1127
0
      value_string_length++;
1128
1129
0
      value_64bit /= 10;
1130
0
    }
1131
0
    while( value_64bit > 0 );
1132
1133
0
    if( ( string_index + value_string_length + 1 ) >= utf32_string_size )
1134
0
    {
1135
0
      libcerror_error_set(
1136
0
       error,
1137
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1138
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1139
0
       "%s: UTF-32 string is too small.",
1140
0
       function );
1141
1142
0
      return( -1 );
1143
0
    }
1144
0
    utf32_string[ string_index++ ] = (uint32_t) '-';
1145
1146
0
    value_64bit        = internal_security_identifier->sub_authority[ sub_authority_index ];
1147
0
    value_string_index = value_string_length;
1148
1149
0
    while( value_string_index > 0 )
1150
0
    {
1151
0
      value_string_index--;
1152
1153
0
      utf32_string[ string_index + value_string_index ] = (uint32_t) '0' + (uint32_t) ( value_64bit % 10 );
1154
1155
0
      value_64bit /= 10;
1156
0
    }
1157
0
    string_index += value_string_length;
1158
0
  }
1159
0
  if( string_index >= utf32_string_size )
1160
0
  {
1161
0
    libcerror_error_set(
1162
0
     error,
1163
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1164
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1165
0
     "%s: UTF-32 string is too small.",
1166
0
     function );
1167
1168
0
    return( -1 );
1169
0
  }
1170
0
  utf32_string[ string_index++ ] = 0;
1171
1172
0
  *utf32_string_index = string_index;
1173
1174
0
  return( 1 );
1175
0
}
1176