Coverage Report

Created: 2026-11-12 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/pkcs12.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
3
 * Copyright (C) 2012 Nikos Mavrogiannopoulos
4
 * Copyright (C) 2017 Red Hat, Inc.
5
 *
6
 * Author: Nikos Mavrogiannopoulos
7
 *
8
 * This file is part of GnuTLS.
9
 *
10
 * The GnuTLS is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public License
12
 * as published by the Free Software Foundation; either version 2.1 of
13
 * the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
22
 *
23
 */
24
25
/* Functions that relate on PKCS12 packet parsing.
26
 */
27
28
#include "gnutls_int.h"
29
#include <libtasn1.h>
30
31
#include "datum.h"
32
#include "global.h"
33
#include "errors.h"
34
#include "num.h"
35
#include "common.h"
36
#include "x509_b64.h"
37
#include "x509_int.h"
38
#include "pkcs7_int.h"
39
#include "random.h"
40
#include "intprops.h"
41
42
1.57k
#define PBMAC1_OID "1.2.840.113549.1.5.14"
43
44
/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
45
 * which holds them. Returns an asn1_node of authenticatedSafe.
46
 */
47
static int _decode_pkcs12_auth_safe(asn1_node pkcs12, asn1_node *authen_safe,
48
            gnutls_datum_t *raw)
49
12.2k
{
50
12.2k
  char oid[MAX_OID_SIZE];
51
12.2k
  asn1_node c2 = NULL;
52
12.2k
  gnutls_datum_t auth_safe = { NULL, 0 };
53
12.2k
  int len, result;
54
12.2k
  char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
55
56
12.2k
  len = sizeof(oid) - 1;
57
12.2k
  result = asn1_read_value(pkcs12, "authSafe.contentType", oid, &len);
58
12.2k
  if (result != ASN1_SUCCESS) {
59
457
    gnutls_assert();
60
457
    return _gnutls_asn2err(result);
61
457
  }
62
63
11.8k
  if (!streq(oid, DATA_OID)) {
64
123
    gnutls_assert();
65
123
    _gnutls_debug_log("Unknown PKCS12 Content OID '%s'\n", oid);
66
123
    return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
67
123
  }
68
69
  /* Step 1. Read the content data
70
   */
71
72
11.7k
  result = _gnutls_x509_read_string(pkcs12, "authSafe.content",
73
11.7k
            &auth_safe, ASN1_ETYPE_OCTET_STRING,
74
11.7k
            1);
75
11.7k
  if (result < 0) {
76
159
    gnutls_assert();
77
159
    goto cleanup;
78
159
  }
79
80
  /* Step 2. Extract the authenticatedSafe.
81
   */
82
83
11.5k
  if ((result = asn1_create_element(_gnutls_get_pkix(),
84
11.5k
            "PKIX1.pkcs-12-AuthenticatedSafe",
85
11.5k
            &c2)) != ASN1_SUCCESS) {
86
0
    gnutls_assert();
87
0
    result = _gnutls_asn2err(result);
88
0
    goto cleanup;
89
0
  }
90
91
11.5k
  result = asn1_der_decoding(&c2, auth_safe.data, auth_safe.size,
92
11.5k
           error_str);
93
11.5k
  if (result != ASN1_SUCCESS) {
94
627
    gnutls_assert();
95
627
    _gnutls_debug_log("DER error: %s\n", error_str);
96
627
    result = _gnutls_asn2err(result);
97
627
    goto cleanup;
98
627
  }
99
100
10.9k
  if (raw == NULL) {
101
10.3k
    _gnutls_free_datum(&auth_safe);
102
10.3k
  } else {
103
572
    raw->data = auth_safe.data;
104
572
    raw->size = auth_safe.size;
105
572
  }
106
107
10.9k
  if (authen_safe)
108
10.3k
    *authen_safe = c2;
109
572
  else
110
572
    asn1_delete_structure(&c2);
111
112
10.9k
  return 0;
113
114
786
cleanup:
115
786
  if (c2)
116
0
    asn1_delete_structure(&c2);
117
786
  _gnutls_free_datum(&auth_safe);
118
786
  return result;
119
11.5k
}
120
121
static int pkcs12_reinit(gnutls_pkcs12_t pkcs12)
122
9.18k
{
123
9.18k
  int result;
124
125
9.18k
  if (pkcs12->pkcs12)
126
0
    asn1_delete_structure(&pkcs12->pkcs12);
127
128
9.18k
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-12-PFX",
129
9.18k
             &pkcs12->pkcs12);
130
9.18k
  if (result != ASN1_SUCCESS) {
131
0
    gnutls_assert();
132
0
    return _gnutls_asn2err(result);
133
0
  }
134
135
9.18k
  return 0;
136
9.18k
}
137
138
/**
139
 * gnutls_pkcs12_init:
140
 * @pkcs12: A pointer to the type to be initialized
141
 *
142
 * This function will initialize a PKCS12 type. PKCS12 structures
143
 * usually contain lists of X.509 Certificates and X.509 Certificate
144
 * revocation lists.
145
 *
146
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
147
 *   negative error value.
148
 **/
149
int gnutls_pkcs12_init(gnutls_pkcs12_t *pkcs12)
150
9.18k
{
151
9.18k
  *pkcs12 = gnutls_calloc(1, sizeof(gnutls_pkcs12_int));
152
153
9.18k
  if (*pkcs12) {
154
9.18k
    int result = pkcs12_reinit(*pkcs12);
155
9.18k
    if (result < 0) {
156
0
      gnutls_assert();
157
0
      gnutls_free(*pkcs12);
158
0
      return result;
159
0
    }
160
9.18k
    return 0; /* success */
161
9.18k
  }
162
0
  return GNUTLS_E_MEMORY_ERROR;
163
9.18k
}
164
165
/**
166
 * gnutls_pkcs12_deinit:
167
 * @pkcs12: The type to be initialized
168
 *
169
 * This function will deinitialize a PKCS12 type.
170
 **/
171
void gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12)
172
9.18k
{
173
9.18k
  if (!pkcs12)
174
0
    return;
175
176
9.18k
  if (pkcs12->pkcs12)
177
6.61k
    asn1_delete_structure(&pkcs12->pkcs12);
178
179
9.18k
  gnutls_free(pkcs12);
180
9.18k
}
181
182
/**
183
 * gnutls_pkcs12_import:
184
 * @pkcs12: The data to store the parsed PKCS12.
185
 * @data: The DER or PEM encoded PKCS12.
186
 * @format: One of DER or PEM
187
 * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags
188
 *
189
 * This function will convert the given DER or PEM encoded PKCS12
190
 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
191
 *
192
 * If the PKCS12 is PEM encoded it should have a header of "PKCS12".
193
 *
194
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
195
 *   negative error value.
196
 **/
197
int gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12, const gnutls_datum_t *data,
198
       gnutls_x509_crt_fmt_t format, unsigned int flags)
199
9.18k
{
200
9.18k
  int result = 0, need_free = 0;
201
9.18k
  gnutls_datum_t _data;
202
9.18k
  char error_str[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
203
204
9.18k
  _data.data = data->data;
205
9.18k
  _data.size = data->size;
206
207
9.18k
  if (pkcs12 == NULL) {
208
0
    gnutls_assert();
209
0
    return GNUTLS_E_INVALID_REQUEST;
210
0
  }
211
212
  /* If the PKCS12 is in PEM format then decode it
213
   */
214
9.18k
  if (format == GNUTLS_X509_FMT_PEM) {
215
0
    result = _gnutls_fbase64_decode(PEM_PKCS12, data->data,
216
0
            data->size, &_data);
217
218
0
    if (result < 0) {
219
0
      gnutls_assert();
220
0
      return result;
221
0
    }
222
223
0
    need_free = 1;
224
0
  }
225
226
9.18k
  if (pkcs12->expanded) {
227
0
    result = pkcs12_reinit(pkcs12);
228
0
    if (result < 0) {
229
0
      gnutls_assert();
230
0
      goto cleanup;
231
0
    }
232
0
  }
233
9.18k
  pkcs12->expanded = 1;
234
235
9.18k
  result = asn1_der_decoding(&pkcs12->pkcs12, _data.data, _data.size,
236
9.18k
           error_str);
237
9.18k
  if (result != ASN1_SUCCESS) {
238
2.56k
    result = _gnutls_asn2err(result);
239
2.56k
    _gnutls_debug_log("DER error: %s\n", error_str);
240
2.56k
    gnutls_assert();
241
2.56k
    goto cleanup;
242
2.56k
  }
243
244
6.61k
  if (need_free)
245
0
    _gnutls_free_datum(&_data);
246
247
6.61k
  return 0;
248
249
2.56k
cleanup:
250
2.56k
  if (need_free)
251
0
    _gnutls_free_datum(&_data);
252
2.56k
  return result;
253
9.18k
}
254
255
/**
256
 * gnutls_pkcs12_export:
257
 * @pkcs12: A pkcs12 type
258
 * @format: the format of output params. One of PEM or DER.
259
 * @output_data: will contain a structure PEM or DER encoded
260
 * @output_data_size: holds the size of output_data (and will be
261
 *   replaced by the actual size of parameters)
262
 *
263
 * This function will export the pkcs12 structure to DER or PEM format.
264
 *
265
 * If the buffer provided is not long enough to hold the output, then
266
 * *output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
267
 * will be returned.
268
 *
269
 * If the structure is PEM encoded, it will have a header
270
 * of "BEGIN PKCS12".
271
 *
272
 * Returns: In case of failure a negative error code will be
273
 *   returned, and 0 on success.
274
 **/
275
int gnutls_pkcs12_export(gnutls_pkcs12_t pkcs12, gnutls_x509_crt_fmt_t format,
276
       void *output_data, size_t *output_data_size)
277
0
{
278
0
  if (pkcs12 == NULL) {
279
0
    gnutls_assert();
280
0
    return GNUTLS_E_INVALID_REQUEST;
281
0
  }
282
283
0
  return _gnutls_x509_export_int(pkcs12->pkcs12, format, PEM_PKCS12,
284
0
               output_data, output_data_size);
285
0
}
286
287
/**
288
 * gnutls_pkcs12_export2:
289
 * @pkcs12: A pkcs12 type
290
 * @format: the format of output params. One of PEM or DER.
291
 * @out: will contain a structure PEM or DER encoded
292
 *
293
 * This function will export the pkcs12 structure to DER or PEM format.
294
 *
295
 * The output buffer is allocated using gnutls_malloc().
296
 *
297
 * If the structure is PEM encoded, it will have a header
298
 * of "BEGIN PKCS12".
299
 *
300
 * Returns: In case of failure a negative error code will be
301
 *   returned, and 0 on success.
302
 *
303
 * Since: 3.1.3
304
 **/
305
int gnutls_pkcs12_export2(gnutls_pkcs12_t pkcs12, gnutls_x509_crt_fmt_t format,
306
        gnutls_datum_t *out)
307
0
{
308
0
  if (pkcs12 == NULL) {
309
0
    gnutls_assert();
310
0
    return GNUTLS_E_INVALID_REQUEST;
311
0
  }
312
313
0
  return _gnutls_x509_export_int2(pkcs12->pkcs12, format, PEM_PKCS12,
314
0
          out);
315
0
}
316
317
static int oid2bag(const char *oid)
318
8.36k
{
319
8.36k
  if (streq(oid, BAG_PKCS8_KEY))
320
7
    return GNUTLS_BAG_PKCS8_KEY;
321
8.35k
  if (streq(oid, BAG_PKCS8_ENCRYPTED_KEY))
322
5.84k
    return GNUTLS_BAG_PKCS8_ENCRYPTED_KEY;
323
2.51k
  if (streq(oid, BAG_CERTIFICATE))
324
1.79k
    return GNUTLS_BAG_CERTIFICATE;
325
719
  if (streq(oid, BAG_CRL))
326
30
    return GNUTLS_BAG_CRL;
327
689
  if (streq(oid, BAG_SECRET))
328
3
    return GNUTLS_BAG_SECRET;
329
330
686
  return GNUTLS_BAG_UNKNOWN;
331
689
}
332
333
static const char *bag_to_oid(int bag)
334
0
{
335
0
  switch (bag) {
336
0
  case GNUTLS_BAG_PKCS8_KEY:
337
0
    return BAG_PKCS8_KEY;
338
0
  case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
339
0
    return BAG_PKCS8_ENCRYPTED_KEY;
340
0
  case GNUTLS_BAG_CERTIFICATE:
341
0
    return BAG_CERTIFICATE;
342
0
  case GNUTLS_BAG_CRL:
343
0
    return BAG_CRL;
344
0
  case GNUTLS_BAG_SECRET:
345
0
    return BAG_SECRET;
346
0
  }
347
0
  return NULL;
348
0
}
349
350
/* Decodes the SafeContents, and puts the output in
351
 * the given bag. 
352
 */
353
int _pkcs12_decode_safe_contents(const gnutls_datum_t *content,
354
         gnutls_pkcs12_bag_t bag)
355
8.34k
{
356
8.34k
  char oid[MAX_OID_SIZE], root[MAX_NAME_SIZE];
357
8.34k
  asn1_node c2 = NULL;
358
8.34k
  int len, result;
359
8.34k
  int bag_type;
360
8.34k
  gnutls_datum_t attr_val;
361
8.34k
  gnutls_datum_t t;
362
8.34k
  int count = 0, attributes, j;
363
8.34k
  unsigned i;
364
365
  /* Step 1. Extract the SEQUENCE.
366
   */
367
368
8.34k
  if ((result = asn1_create_element(_gnutls_get_pkix(),
369
8.34k
            "PKIX1.pkcs-12-SafeContents", &c2)) !=
370
8.34k
      ASN1_SUCCESS) {
371
0
    gnutls_assert();
372
0
    result = _gnutls_asn2err(result);
373
0
    goto cleanup;
374
0
  }
375
376
8.34k
  result = asn1_der_decoding(&c2, content->data, content->size, NULL);
377
8.34k
  if (result != ASN1_SUCCESS) {
378
89
    gnutls_assert();
379
89
    result = _gnutls_asn2err(result);
380
89
    goto cleanup;
381
89
  }
382
383
  /* Count the number of bags
384
   */
385
8.25k
  result = asn1_number_of_elements(c2, "", &count);
386
8.25k
  if (result != ASN1_SUCCESS) {
387
0
    gnutls_assert();
388
0
    result = _gnutls_asn2err(result);
389
0
    goto cleanup;
390
0
  }
391
392
8.25k
  bag->bag_elements = MIN(MAX_BAG_ELEMENTS, count);
393
394
16.6k
  for (i = 0; i < bag->bag_elements; i++) {
395
8.37k
    snprintf(root, sizeof(root), "?%u.bagId", i + 1);
396
397
8.37k
    len = sizeof(oid);
398
8.37k
    result = asn1_read_value(c2, root, oid, &len);
399
8.37k
    if (result != ASN1_SUCCESS) {
400
5
      gnutls_assert();
401
5
      result = _gnutls_asn2err(result);
402
5
      goto cleanup;
403
5
    }
404
405
    /* Read the Bag type
406
     */
407
8.36k
    bag_type = oid2bag(oid);
408
409
8.36k
    if (bag_type < 0) {
410
0
      gnutls_assert();
411
0
      goto cleanup;
412
0
    }
413
414
    /* Read the Bag Value
415
     */
416
417
8.36k
    snprintf(root, sizeof(root), "?%u.bagValue", i + 1);
418
419
8.36k
    result = _gnutls_x509_read_value(c2, root,
420
8.36k
             &bag->element[i].data);
421
8.36k
    if (result < 0) {
422
0
      gnutls_assert();
423
0
      goto cleanup;
424
0
    }
425
426
8.36k
    if (bag_type == GNUTLS_BAG_CERTIFICATE ||
427
6.57k
        bag_type == GNUTLS_BAG_CRL ||
428
6.54k
        bag_type == GNUTLS_BAG_SECRET) {
429
1.82k
      gnutls_datum_t tmp = bag->element[i].data;
430
1.82k
      bag->element[i].data.data = NULL;
431
1.82k
      bag->element[i].data.size = 0;
432
433
1.82k
      result = _pkcs12_decode_crt_bag(bag_type, &tmp,
434
1.82k
              &bag->element[i].data);
435
1.82k
      _gnutls_free_datum(&tmp);
436
1.82k
      if (result < 0) {
437
8
        gnutls_assert();
438
8
        goto cleanup;
439
8
      }
440
1.82k
    }
441
442
    /* read the bag attributes
443
     */
444
8.35k
    snprintf(root, sizeof(root), "?%u.bagAttributes", i + 1);
445
446
8.35k
    result = asn1_number_of_elements(c2, root, &attributes);
447
8.35k
    if (result != ASN1_SUCCESS &&
448
222
        result != ASN1_ELEMENT_NOT_FOUND) {
449
0
      gnutls_assert();
450
0
      result = _gnutls_asn2err(result);
451
0
      goto cleanup;
452
0
    }
453
454
8.35k
    if (attributes < 0)
455
0
      attributes = 1;
456
457
8.35k
    if (result != ASN1_ELEMENT_NOT_FOUND)
458
24.5k
      for (j = 0; j < attributes; j++) {
459
16.4k
        snprintf(root, sizeof(root),
460
16.4k
           "?%u.bagAttributes.?%d", i + 1, j + 1);
461
462
16.4k
        result = _gnutls_x509_decode_and_read_attribute(
463
16.4k
          c2, root, oid, sizeof(oid), &attr_val,
464
16.4k
          1, 0);
465
466
16.4k
        if (result < 0) {
467
128
          gnutls_assert();
468
128
          continue; /* continue in case we find some known attributes */
469
128
        }
470
471
16.2k
        if (streq(oid, KEY_ID_OID)) {
472
1.91k
          result = _gnutls_x509_decode_string(
473
1.91k
            ASN1_ETYPE_OCTET_STRING,
474
1.91k
            attr_val.data, attr_val.size,
475
1.91k
            &t, 1);
476
477
1.91k
          _gnutls_free_datum(&attr_val);
478
1.91k
          if (result < 0) {
479
236
            gnutls_assert();
480
236
            _gnutls_debug_log(
481
236
              "Error decoding PKCS12 Bag Attribute OID '%s'\n",
482
236
              oid);
483
236
            continue;
484
236
          }
485
486
1.68k
          _gnutls_free_datum(
487
1.68k
            &bag->element[i].local_key_id);
488
1.68k
          bag->element[i].local_key_id.data =
489
1.68k
            t.data;
490
1.68k
          bag->element[i].local_key_id.size =
491
1.68k
            t.size;
492
14.3k
        } else if (streq(oid, FRIENDLY_NAME_OID) &&
493
2.42k
             bag->element[i].friendly_name ==
494
2.42k
               NULL) {
495
2.41k
          result = _gnutls_x509_decode_string(
496
2.41k
            ASN1_ETYPE_BMP_STRING,
497
2.41k
            attr_val.data, attr_val.size,
498
2.41k
            &t, 1);
499
500
2.41k
          _gnutls_free_datum(&attr_val);
501
2.41k
          if (result < 0) {
502
323
            gnutls_assert();
503
323
            _gnutls_debug_log(
504
323
              "Error decoding PKCS12 Bag Attribute OID '%s'\n",
505
323
              oid);
506
323
            continue;
507
323
          }
508
509
2.09k
          gnutls_free(
510
2.09k
            bag->element[i].friendly_name);
511
2.09k
          bag->element[i].friendly_name =
512
2.09k
            (char *)t.data;
513
11.9k
        } else {
514
11.9k
          _gnutls_free_datum(&attr_val);
515
11.9k
          _gnutls_debug_log(
516
11.9k
            "Unknown PKCS12 Bag Attribute OID '%s'\n",
517
11.9k
            oid);
518
11.9k
        }
519
16.2k
      }
520
521
8.35k
    bag->element[i].type = bag_type;
522
8.35k
  }
523
524
8.23k
  result = 0;
525
526
8.34k
cleanup:
527
8.34k
  if (c2)
528
8.25k
    asn1_delete_structure(&c2);
529
8.34k
  return result;
530
8.23k
}
531
532
static int _parse_safe_contents(asn1_node sc, const char *sc_name,
533
        gnutls_pkcs12_bag_t bag)
534
6.00k
{
535
6.00k
  gnutls_datum_t content = { NULL, 0 };
536
6.00k
  int result;
537
538
  /* Step 1. Extract the content.
539
   */
540
541
6.00k
  result = _gnutls_x509_read_string(sc, sc_name, &content,
542
6.00k
            ASN1_ETYPE_OCTET_STRING, 1);
543
6.00k
  if (result < 0) {
544
4
    gnutls_assert();
545
4
    goto cleanup;
546
4
  }
547
548
6.00k
  result = _pkcs12_decode_safe_contents(&content, bag);
549
6.00k
  if (result < 0) {
550
44
    gnutls_assert();
551
44
    goto cleanup;
552
44
  }
553
554
5.95k
  _gnutls_free_datum(&content);
555
556
5.95k
  return 0;
557
558
48
cleanup:
559
48
  _gnutls_free_datum(&content);
560
48
  return result;
561
6.00k
}
562
563
/**
564
 * gnutls_pkcs12_get_bag:
565
 * @pkcs12: A pkcs12 type
566
 * @indx: contains the index of the bag to extract
567
 * @bag: An initialized bag, where the contents of the bag will be copied
568
 *
569
 * This function will return a Bag from the PKCS12 structure.
570
 *
571
 * After the last Bag has been read
572
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
573
 *
574
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
575
 *   negative error value.
576
 **/
577
int gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12, int indx,
578
        gnutls_pkcs12_bag_t bag)
579
11.2k
{
580
11.2k
  asn1_node c2 = NULL;
581
11.2k
  int result, len;
582
11.2k
  char root2[MAX_NAME_SIZE];
583
11.2k
  char oid[MAX_OID_SIZE];
584
585
11.2k
  if (pkcs12 == NULL) {
586
0
    gnutls_assert();
587
0
    return GNUTLS_E_INVALID_REQUEST;
588
0
  }
589
590
  /* Step 1. decode the data.
591
   */
592
11.2k
  result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, &c2, NULL);
593
11.2k
  if (result < 0) {
594
935
    gnutls_assert();
595
935
    return result;
596
935
  }
597
598
  /* Step 2. Parse the AuthenticatedSafe
599
   */
600
601
10.3k
  snprintf(root2, sizeof(root2), "?%d.contentType", indx + 1);
602
603
10.3k
  len = sizeof(oid) - 1;
604
10.3k
  result = asn1_read_value(c2, root2, oid, &len);
605
606
10.3k
  if (result == ASN1_ELEMENT_NOT_FOUND) {
607
1.49k
    result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
608
1.49k
    goto cleanup;
609
1.49k
  }
610
611
8.85k
  if (result != ASN1_SUCCESS) {
612
1
    gnutls_assert();
613
1
    result = _gnutls_asn2err(result);
614
1
    goto cleanup;
615
1
  }
616
617
  /* Not encrypted Bag
618
   */
619
620
8.85k
  snprintf(root2, sizeof(root2), "?%d.content", indx + 1);
621
622
8.85k
  if (streq(oid, DATA_OID)) {
623
6.00k
    result = _parse_safe_contents(c2, root2, bag);
624
6.00k
    goto cleanup;
625
6.00k
  }
626
627
  /* ENC_DATA_OID needs decryption */
628
629
2.85k
  result = _gnutls_x509_read_value(c2, root2, &bag->element[0].data);
630
2.85k
  if (result < 0) {
631
0
    gnutls_assert();
632
0
    goto cleanup;
633
0
  }
634
635
2.85k
  bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
636
2.85k
  bag->bag_elements = 1;
637
638
2.85k
  result = 0;
639
640
10.3k
cleanup:
641
10.3k
  if (c2)
642
10.3k
    asn1_delete_structure(&c2);
643
10.3k
  return result;
644
2.85k
}
645
646
/* Creates an empty PFX structure for the PKCS12 structure.
647
 */
648
static int create_empty_pfx(asn1_node pkcs12)
649
0
{
650
0
  uint8_t three = 3;
651
0
  int result;
652
0
  asn1_node c2 = NULL;
653
654
  /* Use version 3
655
   */
656
0
  result = asn1_write_value(pkcs12, "version", &three, 1);
657
0
  if (result != ASN1_SUCCESS) {
658
0
    gnutls_assert();
659
0
    result = _gnutls_asn2err(result);
660
0
    goto cleanup;
661
0
  }
662
663
  /* Write the content type of the data
664
   */
665
0
  result = asn1_write_value(pkcs12, "authSafe.contentType", DATA_OID, 1);
666
0
  if (result != ASN1_SUCCESS) {
667
0
    gnutls_assert();
668
0
    result = _gnutls_asn2err(result);
669
0
    goto cleanup;
670
0
  }
671
672
  /* Check if the authenticatedSafe content is empty, and encode a
673
   * null one in that case.
674
   */
675
676
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
677
0
            "PKIX1.pkcs-12-AuthenticatedSafe",
678
0
            &c2)) != ASN1_SUCCESS) {
679
0
    gnutls_assert();
680
0
    result = _gnutls_asn2err(result);
681
0
    goto cleanup;
682
0
  }
683
684
0
  result = _gnutls_x509_der_encode_and_copy(c2, "", pkcs12,
685
0
              "authSafe.content", 1);
686
0
  if (result < 0) {
687
0
    gnutls_assert();
688
0
    goto cleanup;
689
0
  }
690
0
  asn1_delete_structure(&c2);
691
692
0
  return 0;
693
694
0
cleanup:
695
0
  asn1_delete_structure(&c2);
696
0
  return result;
697
0
}
698
699
/**
700
 * gnutls_pkcs12_set_bag:
701
 * @pkcs12: should contain a gnutls_pkcs12_t type
702
 * @bag: An initialized bag
703
 *
704
 * This function will insert a Bag into the PKCS12 structure.
705
 *
706
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
707
 *   negative error value.
708
 **/
709
int gnutls_pkcs12_set_bag(gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag)
710
0
{
711
0
  asn1_node c2 = NULL;
712
0
  asn1_node safe_cont = NULL;
713
0
  int result;
714
0
  int enc = 0, dum = 1;
715
0
  char null;
716
717
0
  if (pkcs12 == NULL) {
718
0
    gnutls_assert();
719
0
    return GNUTLS_E_INVALID_REQUEST;
720
0
  }
721
722
  /* Step 1. Check if the pkcs12 structure is empty. In that
723
   * case generate an empty PFX.
724
   */
725
0
  result = asn1_read_value(pkcs12->pkcs12, "authSafe.content", &null,
726
0
         &dum);
727
0
  if (result == ASN1_VALUE_NOT_FOUND) {
728
0
    result = create_empty_pfx(pkcs12->pkcs12);
729
0
    if (result < 0) {
730
0
      gnutls_assert();
731
0
      return result;
732
0
    }
733
0
  }
734
735
  /* Step 2. decode the authenticatedSafe.
736
   */
737
0
  result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, &c2, NULL);
738
0
  if (result < 0) {
739
0
    gnutls_assert();
740
0
    return result;
741
0
  }
742
743
  /* Step 3. Encode the bag elements into a SafeContents 
744
   * structure.
745
   */
746
0
  result = _pkcs12_encode_safe_contents(bag, &safe_cont, &enc);
747
0
  if (result < 0) {
748
0
    gnutls_assert();
749
0
    return result;
750
0
  }
751
752
  /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
753
   * structure.
754
   */
755
0
  result = asn1_write_value(c2, "", "NEW", 1);
756
0
  if (result != ASN1_SUCCESS) {
757
0
    gnutls_assert();
758
0
    result = _gnutls_asn2err(result);
759
0
    goto cleanup;
760
0
  }
761
762
0
  if (enc)
763
0
    result = asn1_write_value(c2, "?LAST.contentType", ENC_DATA_OID,
764
0
            1);
765
0
  else
766
0
    result = asn1_write_value(c2, "?LAST.contentType", DATA_OID, 1);
767
0
  if (result != ASN1_SUCCESS) {
768
0
    gnutls_assert();
769
0
    result = _gnutls_asn2err(result);
770
0
    goto cleanup;
771
0
  }
772
773
0
  if (enc) {
774
    /* Encrypted packets are written directly.
775
     */
776
0
    result = asn1_write_value(c2, "?LAST.content",
777
0
            bag->element[0].data.data,
778
0
            bag->element[0].data.size);
779
0
    if (result != ASN1_SUCCESS) {
780
0
      gnutls_assert();
781
0
      result = _gnutls_asn2err(result);
782
0
      goto cleanup;
783
0
    }
784
0
  } else {
785
0
    result = _gnutls_x509_der_encode_and_copy(safe_cont, "", c2,
786
0
                "?LAST.content", 1);
787
0
    if (result < 0) {
788
0
      gnutls_assert();
789
0
      goto cleanup;
790
0
    }
791
0
  }
792
793
0
  asn1_delete_structure(&safe_cont);
794
795
  /* Step 5. Re-encode and copy the AuthenticatedSafe into the pkcs12
796
   * structure.
797
   */
798
0
  result = _gnutls_x509_der_encode_and_copy(c2, "", pkcs12->pkcs12,
799
0
              "authSafe.content", 1);
800
0
  if (result < 0) {
801
0
    gnutls_assert();
802
0
    goto cleanup;
803
0
  }
804
805
0
  asn1_delete_structure(&c2);
806
807
0
  return 0;
808
809
0
cleanup:
810
0
  asn1_delete_structure(&c2);
811
0
  asn1_delete_structure(&safe_cont);
812
0
  return result;
813
0
}
814
815
#if ENABLE_GOST
816
/*
817
 * Russian differs from PKCS#12 here. It described proprietary way
818
 * to obtain MAC key instead of using standard mechanism.
819
 *
820
 * See https://wwwold.tc26.ru/standard/rs/%D0%A0%2050.1.112-2016.pdf
821
 * section 5.
822
 */
823
static int
824
_gnutls_pkcs12_gost_string_to_key(gnutls_mac_algorithm_t algo,
825
          const uint8_t *salt, unsigned int salt_size,
826
          unsigned int iter, const char *pass,
827
          unsigned int req_keylen, uint8_t *keybuf)
828
234
{
829
234
  uint8_t temp[96];
830
234
  size_t temp_len = sizeof(temp);
831
234
  gnutls_datum_t key;
832
234
  gnutls_datum_t _salt;
833
234
  int ret;
834
835
234
  if (iter == 0)
836
9
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
837
838
225
  key.data = (void *)pass;
839
225
  key.size = pass ? strlen(pass) : 0;
840
841
225
  _salt.data = (void *)salt;
842
225
  _salt.size = salt_size;
843
844
225
  ret = gnutls_pbkdf2(algo, &key, &_salt, iter, temp, temp_len);
845
225
  if (ret < 0)
846
0
    return gnutls_assert_val(ret);
847
848
225
  memcpy(keybuf, temp + temp_len - req_keylen, req_keylen);
849
850
225
  return 0;
851
225
}
852
#endif
853
854
static int generate_mac_pbmac1(gnutls_mac_algorithm_t mac,
855
             const gnutls_datum_t *key,
856
             const struct pbkdf2_params *params,
857
             const gnutls_datum_t *data, asn1_node pkcs12)
858
0
{
859
0
  uint8_t mac_output_data[MAX_HASH_SIZE];
860
0
  gnutls_datum_t mac_output;
861
0
  int result;
862
863
0
  result = _gnutls_pbmac1(mac, key, params, data, mac_output_data);
864
0
  if (result < 0) {
865
0
    gnutls_assert();
866
0
    return result;
867
0
  }
868
869
0
  mac_output.data = mac_output_data;
870
0
  mac_output.size = params->key_size;
871
872
0
  result = _gnutls_x509_write_value(pkcs12, "macData.mac.digest",
873
0
            &mac_output);
874
0
  if (result < 0) {
875
0
    gnutls_assert();
876
0
    return result;
877
0
  }
878
879
0
  result = asn1_write_value(
880
0
    pkcs12, "macData.mac.digestAlgorithm.algorithm", PBMAC1_OID, 1);
881
0
  if (result != ASN1_SUCCESS) {
882
0
    gnutls_assert();
883
0
    return _gnutls_asn2err(result);
884
0
  }
885
886
0
  result = _gnutls_write_pbmac1_params(
887
0
    pkcs12, params, mac, "macData.mac.digestAlgorithm.parameters");
888
0
  if (result < 0) {
889
0
    gnutls_assert();
890
0
    return result;
891
0
  }
892
893
0
  return 0;
894
0
}
895
896
static int generate_mac_pkcs12(const mac_entry_st *me,
897
             const gnutls_datum_t *key,
898
             const gnutls_datum_t *salt, unsigned iter_count,
899
             const gnutls_datum_t *data, asn1_node pkcs12)
900
0
{
901
0
  gnutls_hmac_hd_t hd;
902
0
  uint8_t mac_key_data[MAX_HASH_SIZE];
903
0
  size_t mac_key_size = _gnutls_mac_get_algo_len(me);
904
0
  uint8_t mac_data[MAX_HASH_SIZE];
905
0
  gnutls_datum_t mac;
906
0
  int result;
907
908
0
#if ENABLE_GOST
909
0
  if (me->id == GNUTLS_MAC_GOSTR_94 ||
910
0
      me->id == GNUTLS_MAC_STREEBOG_256 ||
911
0
      me->id == GNUTLS_MAC_STREEBOG_512) {
912
0
    mac_key_size = 32;
913
0
    result = _gnutls_pkcs12_gost_string_to_key(
914
0
      me->id, salt->data, salt->size, iter_count,
915
0
      (const char *)key->data, mac_key_size, mac_key_data);
916
0
  } else
917
0
#endif
918
0
    result = _gnutls_pkcs12_string_to_key(
919
0
      me, 3 /*MAC*/, salt->data, salt->size, iter_count,
920
0
      (const char *)key->data, mac_key_size, mac_key_data);
921
0
  if (result < 0) {
922
0
    gnutls_assert();
923
0
    return result;
924
0
  }
925
926
  /* MAC the data.
927
   */
928
0
  result = gnutls_hmac_init(&hd, me->id, mac_key_data, mac_key_size);
929
0
  if (result < 0) {
930
0
    gnutls_assert();
931
0
    return result;
932
0
  }
933
934
0
  gnutls_hmac(hd, data->data, data->size);
935
936
0
  gnutls_hmac_deinit(hd, mac_data);
937
938
0
  mac.data = mac_data;
939
0
  mac.size = _gnutls_mac_get_algo_len(me);
940
941
0
  result = _gnutls_x509_write_value(pkcs12, "macData.mac.digest", &mac);
942
0
  if (result < 0) {
943
0
    gnutls_assert();
944
0
    return result;
945
0
  }
946
947
0
  result = asn1_write_value(
948
0
    pkcs12, "macData.mac.digestAlgorithm.algorithm", me->oid, 1);
949
0
  if (result != ASN1_SUCCESS) {
950
0
    gnutls_assert();
951
0
    return _gnutls_asn2err(result);
952
0
  }
953
954
0
  result = asn1_write_value(
955
0
    pkcs12, "macData.mac.digestAlgorithm.parameters", NULL, 0);
956
0
  if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
957
0
    gnutls_assert();
958
0
    return _gnutls_asn2err(result);
959
0
  }
960
961
  /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */
962
0
  _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
963
964
0
  return 0;
965
0
}
966
967
/**
968
 * gnutls_pkcs12_generate_mac3:
969
 * @pkcs12: A pkcs12 type
970
 * @mac: the MAC algorithm to use
971
 * @pass: The password for the MAC
972
 * @flags: an ORed sequence of gnutls_pkcs12_flags_t
973
 *
974
 * This function will generate a MAC for the PKCS12 structure.
975
 *
976
 * If @flags contains %GNUTLS_PKCS12_USE_PBMAC1, it uses PBMAC1 key
977
 * derivation function instead of the PKCS#12 one.
978
 *
979
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
980
 *   negative error value.
981
 **/
982
int gnutls_pkcs12_generate_mac3(gnutls_pkcs12_t pkcs12,
983
        gnutls_mac_algorithm_t mac, const char *pass,
984
        unsigned int flags)
985
0
{
986
0
  uint8_t salt_data[8];
987
0
  gnutls_datum_t salt, key;
988
0
  const int iter_count = PKCS12_ITER_COUNT;
989
0
  int result;
990
0
  gnutls_datum_t data = { NULL, 0 };
991
0
  const mac_entry_st *me = mac_to_entry(mac);
992
993
0
  if (pkcs12 == NULL || me == NULL)
994
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
995
996
0
  if (me->oid == NULL)
997
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
998
999
  /* Enable PBMAC1 by default in FIPS mode; otherwise the MAC
1000
   * calculation will be FIPS non-compliant.
1001
   */
1002
0
  if (_gnutls_fips_mode_enabled())
1003
0
    flags |= GNUTLS_PKCS12_USE_PBMAC1;
1004
1005
  /* Generate the salt.
1006
   */
1007
0
  salt.data = salt_data;
1008
0
  salt.size = sizeof(salt_data);
1009
1010
0
  result = gnutls_rnd(GNUTLS_RND_NONCE, salt.data, salt.size);
1011
0
  if (result < 0) {
1012
0
    gnutls_assert();
1013
0
    return result;
1014
0
  }
1015
1016
  /* Write the salt into the structure.
1017
   */
1018
0
  result = _gnutls_x509_write_value(pkcs12->pkcs12, "macData.macSalt",
1019
0
            &salt);
1020
0
  if (result < 0) {
1021
0
    gnutls_assert();
1022
0
    goto cleanup;
1023
0
  }
1024
1025
  /* Write the iteration count into the structure.
1026
   */
1027
0
  result = _gnutls_x509_write_uint32(pkcs12->pkcs12, "macData.iterations",
1028
0
             iter_count);
1029
0
  if (result < 0) {
1030
0
    gnutls_assert();
1031
0
    goto cleanup;
1032
0
  }
1033
1034
  /* Get the data to be MACed.
1035
   */
1036
0
  result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &data);
1037
0
  if (result < 0) {
1038
0
    gnutls_assert();
1039
0
    goto cleanup;
1040
0
  }
1041
1042
0
  key.data = (void *)pass;
1043
0
  key.size = strlen(pass);
1044
1045
0
  if (flags & GNUTLS_PKCS12_USE_PBMAC1) {
1046
0
    struct pbkdf2_params kdf_params;
1047
1048
0
    memcpy(kdf_params.salt, salt.data, salt.size);
1049
0
    kdf_params.salt_size = salt.size;
1050
0
    kdf_params.iter_count = iter_count;
1051
0
    kdf_params.key_size = _gnutls_mac_get_algo_len(me);
1052
0
    kdf_params.mac = GNUTLS_MAC_SHA256;
1053
1054
0
    result = generate_mac_pbmac1(me->id, &key, &kdf_params, &data,
1055
0
               pkcs12->pkcs12);
1056
0
  } else
1057
0
    result = generate_mac_pkcs12(me, &key, &salt, iter_count, &data,
1058
0
               pkcs12->pkcs12);
1059
1060
0
cleanup:
1061
0
  if (result < 0)
1062
0
    _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
1063
0
  _gnutls_free_datum(&data);
1064
0
  return result;
1065
0
}
1066
1067
/**
1068
 * gnutls_pkcs12_generate_mac2:
1069
 * @pkcs12: A pkcs12 type
1070
 * @mac: the MAC algorithm to use
1071
 * @pass: The password for the MAC
1072
 *
1073
 * This function will generate a MAC for the PKCS12 structure.
1074
 *
1075
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1076
 *   negative error value.
1077
 **/
1078
int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12,
1079
        gnutls_mac_algorithm_t mac, const char *pass)
1080
0
{
1081
0
  return gnutls_pkcs12_generate_mac3(pkcs12, mac, pass, 0);
1082
0
}
1083
1084
/**
1085
 * gnutls_pkcs12_generate_mac:
1086
 * @pkcs12: A pkcs12 type
1087
 * @pass: The password for the MAC
1088
 *
1089
 * This function will generate a MAC for the PKCS12 structure.
1090
 *
1091
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1092
 *   negative error value.
1093
 **/
1094
int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12, const char *pass)
1095
0
{
1096
0
  return gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA256, pass);
1097
0
}
1098
1099
static int pkcs12_verify_mac_pbmac1(gnutls_pkcs12_t pkcs12, const char *pass)
1100
6
{
1101
6
  int result;
1102
6
  int len;
1103
6
  gnutls_datum_t params = { NULL, 0 }, data = { NULL, 0 };
1104
6
  gnutls_datum_t key;
1105
6
  uint8_t mac_output[MAX_HASH_SIZE];
1106
6
  uint8_t mac_output_orig[MAX_HASH_SIZE];
1107
6
  struct pbkdf2_params kdf_params;
1108
6
  gnutls_mac_algorithm_t algo = GNUTLS_MAC_UNKNOWN;
1109
6
  const mac_entry_st *me;
1110
1111
6
  result = _gnutls_x509_read_value(
1112
6
    pkcs12->pkcs12, "macData.mac.digestAlgorithm.parameters",
1113
6
    &params);
1114
6
  if (result < 0) {
1115
0
    return gnutls_assert_val(result);
1116
0
  }
1117
1118
6
  memset(&kdf_params, 0, sizeof(kdf_params));
1119
6
  result = _gnutls_read_pbmac1_params(params.data, params.size,
1120
6
              &kdf_params, &algo);
1121
6
  if (result < 0) {
1122
6
    gnutls_assert();
1123
6
    goto cleanup;
1124
6
  }
1125
1126
0
  me = mac_to_entry(algo);
1127
0
  if (unlikely(me == NULL)) {
1128
0
    gnutls_assert();
1129
0
    result = GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
1130
0
    goto cleanup;
1131
0
  }
1132
1133
  /* Get the data to be MACed
1134
   */
1135
0
  result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &data);
1136
0
  if (result < 0) {
1137
0
    gnutls_assert();
1138
0
    goto cleanup;
1139
0
  }
1140
1141
0
  key.data = (void *)pass;
1142
0
  key.size = strlen(pass);
1143
1144
0
  result = _gnutls_pbmac1(me->id, &key, &kdf_params, &data, mac_output);
1145
0
  if (result < 0) {
1146
0
    gnutls_assert();
1147
0
    goto cleanup;
1148
0
  }
1149
1150
0
  len = sizeof(mac_output_orig);
1151
0
  result = asn1_read_value(pkcs12->pkcs12, "macData.mac.digest",
1152
0
         mac_output_orig, &len);
1153
0
  if (result != ASN1_SUCCESS) {
1154
0
    gnutls_assert();
1155
0
    result = _gnutls_asn2err(result);
1156
0
    goto cleanup;
1157
0
  }
1158
1159
0
  if ((unsigned)len != _gnutls_mac_get_algo_len(me) ||
1160
0
      !memeq(mac_output_orig, mac_output, len)) {
1161
0
    gnutls_assert();
1162
0
    result = GNUTLS_E_MAC_VERIFY_FAILED;
1163
0
    goto cleanup;
1164
0
  }
1165
1166
6
cleanup:
1167
6
  _gnutls_free_datum(&params);
1168
6
  _gnutls_free_datum(&data);
1169
6
  return result;
1170
0
}
1171
1172
static int pkcs12_verify_mac_pkcs12(gnutls_pkcs12_t pkcs12,
1173
            gnutls_mac_algorithm_t algo,
1174
            const char *pass)
1175
1.56k
{
1176
1.56k
  const mac_entry_st *entry;
1177
1.56k
  uint8_t key[MAX_HASH_SIZE];
1178
1.56k
  uint8_t mac_output[MAX_HASH_SIZE];
1179
1.56k
  uint8_t mac_output_orig[MAX_HASH_SIZE];
1180
1.56k
  gnutls_datum_t tmp = { NULL, 0 }, salt = { NULL, 0 };
1181
1.56k
  unsigned mac_len, key_len;
1182
1.56k
  int len;
1183
1.56k
  gnutls_hmac_hd_t td1;
1184
1.56k
  unsigned iter_count;
1185
1.56k
#if ENABLE_GOST
1186
1.56k
  int gost_retry = 0;
1187
1.56k
#endif
1188
1.56k
  int result;
1189
1190
1.56k
  entry = mac_to_entry(algo);
1191
1.56k
  if (unlikely(entry == NULL)) {
1192
531
    return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM);
1193
531
  }
1194
1195
1.03k
  mac_len = _gnutls_mac_get_algo_len(entry);
1196
1.03k
  key_len = mac_len;
1197
1198
  /* Read the iterations from the structure.
1199
   */
1200
1.03k
  result = _gnutls_x509_read_uint(pkcs12->pkcs12, "macData.iterations",
1201
1.03k
          &iter_count);
1202
1.03k
  if (result < 0) {
1203
99
    iter_count = 1; /* the default */
1204
99
  }
1205
1206
  /* Read the salt from the structure.
1207
   */
1208
1.03k
  result = _gnutls_x509_read_null_value(pkcs12->pkcs12, "macData.macSalt",
1209
1.03k
                &salt);
1210
1.03k
  if (result < 0) {
1211
1
    gnutls_assert();
1212
1
    goto cleanup;
1213
1
  }
1214
1215
  /* Generate the key.
1216
   */
1217
1.03k
  result = _gnutls_pkcs12_string_to_key(entry, 3 /*MAC*/, salt.data,
1218
1.03k
                salt.size, iter_count, pass,
1219
1.03k
                key_len, key);
1220
1.03k
  if (result < 0) {
1221
29
    gnutls_assert();
1222
29
    goto cleanup;
1223
29
  }
1224
1225
  /* Get the data to be MACed.
1226
   */
1227
1.00k
  result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &tmp);
1228
1.00k
  if (result < 0) {
1229
431
    gnutls_assert();
1230
431
    goto cleanup;
1231
431
  }
1232
572
#if ENABLE_GOST
1233
  /* GOST PKCS#12 files use either PKCS#12 scheme or proprietary
1234
   * HMAC-based scheme to generate MAC key. */
1235
797
pkcs12_try_gost:
1236
797
#endif
1237
1238
  /* MAC the data.
1239
   */
1240
797
  result = gnutls_hmac_init(&td1, entry->id, key, key_len);
1241
797
  if (result < 0) {
1242
0
    gnutls_assert();
1243
0
    goto cleanup;
1244
0
  }
1245
1246
797
  gnutls_hmac(td1, tmp.data, tmp.size);
1247
1248
797
  gnutls_hmac_deinit(td1, mac_output);
1249
1250
797
  len = sizeof(mac_output_orig);
1251
797
  result = asn1_read_value(pkcs12->pkcs12, "macData.mac.digest",
1252
797
         mac_output_orig, &len);
1253
797
  if (result != ASN1_SUCCESS) {
1254
1
    gnutls_assert();
1255
1
    result = _gnutls_asn2err(result);
1256
1
    goto cleanup;
1257
1
  }
1258
1259
796
  if ((unsigned)len != mac_len ||
1260
790
      !memeq(mac_output_orig, mac_output, len)) {
1261
790
#if ENABLE_GOST
1262
    /* It is possible that GOST files use proprietary
1263
     * key generation scheme */
1264
790
    if (!gost_retry && (algo == GNUTLS_MAC_GOSTR_94 ||
1265
415
            algo == GNUTLS_MAC_STREEBOG_256 ||
1266
388
            algo == GNUTLS_MAC_STREEBOG_512)) {
1267
234
      gost_retry = 1;
1268
234
      key_len = 32;
1269
234
      result = _gnutls_pkcs12_gost_string_to_key(
1270
234
        algo, salt.data, salt.size, iter_count, pass,
1271
234
        key_len, key);
1272
234
      if (result < 0) {
1273
9
        gnutls_assert();
1274
9
        goto cleanup;
1275
9
      }
1276
1277
225
      goto pkcs12_try_gost;
1278
234
    }
1279
556
#endif
1280
1281
556
    gnutls_assert();
1282
556
    result = GNUTLS_E_MAC_VERIFY_FAILED;
1283
556
    goto cleanup;
1284
790
  }
1285
1286
  /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */
1287
6
  _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
1288
6
  result = 0;
1289
1.03k
cleanup:
1290
1.03k
  _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
1291
1.03k
  _gnutls_free_datum(&tmp);
1292
1.03k
  _gnutls_free_datum(&salt);
1293
1.03k
  return result;
1294
6
}
1295
1296
/**
1297
 * gnutls_pkcs12_verify_mac:
1298
 * @pkcs12: should contain a gnutls_pkcs12_t type
1299
 * @pass: The password for the MAC
1300
 *
1301
 * This function will verify the MAC for the PKCS12 structure.
1302
 *
1303
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1304
 *   negative error value.
1305
 **/
1306
int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12, const char *pass)
1307
6.61k
{
1308
6.61k
  char oid[MAX_OID_SIZE];
1309
6.61k
  int result;
1310
6.61k
  int len;
1311
1312
6.61k
  if (pkcs12 == NULL) {
1313
0
    gnutls_assert();
1314
0
    return GNUTLS_E_INVALID_REQUEST;
1315
0
  }
1316
1317
6.61k
  len = sizeof(oid);
1318
6.61k
  result = asn1_read_value(pkcs12->pkcs12,
1319
6.61k
         "macData.mac.digestAlgorithm.algorithm", oid,
1320
6.61k
         &len);
1321
6.61k
  if (result != ASN1_SUCCESS) {
1322
5.04k
    gnutls_assert();
1323
5.04k
    return _gnutls_asn2err(result);
1324
5.04k
  }
1325
1326
1.57k
  if (streq(oid, PBMAC1_OID)) {
1327
6
    return pkcs12_verify_mac_pbmac1(pkcs12, pass);
1328
1.56k
  } else {
1329
1.56k
    gnutls_mac_algorithm_t algo;
1330
1331
1.56k
    algo = DIG_TO_MAC(gnutls_oid_to_digest(oid));
1332
1.56k
    return pkcs12_verify_mac_pkcs12(pkcs12, algo, pass);
1333
1.56k
  }
1334
1.57k
}
1335
1336
static int write_attributes(gnutls_pkcs12_bag_t bag, int elem, asn1_node c2,
1337
          const char *where)
1338
0
{
1339
0
  int result;
1340
0
  char root[128];
1341
1342
  /* If the bag attributes are empty, then write
1343
   * nothing to the attribute field.
1344
   */
1345
0
  if (bag->element[elem].friendly_name == NULL &&
1346
0
      bag->element[elem].local_key_id.data == NULL) {
1347
    /* no attributes
1348
     */
1349
0
    result = asn1_write_value(c2, where, NULL, 0);
1350
0
    if (result != ASN1_SUCCESS) {
1351
0
      gnutls_assert();
1352
0
      return _gnutls_asn2err(result);
1353
0
    }
1354
1355
0
    return 0;
1356
0
  }
1357
1358
0
  if (bag->element[elem].local_key_id.data != NULL) {
1359
    /* Add a new Attribute
1360
     */
1361
0
    result = asn1_write_value(c2, where, "NEW", 1);
1362
0
    if (result != ASN1_SUCCESS) {
1363
0
      gnutls_assert();
1364
0
      return _gnutls_asn2err(result);
1365
0
    }
1366
1367
0
    _gnutls_str_cpy(root, sizeof(root), where);
1368
0
    _gnutls_str_cat(root, sizeof(root), ".?LAST");
1369
1370
0
    result = _gnutls_x509_encode_and_write_attribute(
1371
0
      KEY_ID_OID, c2, root,
1372
0
      bag->element[elem].local_key_id.data,
1373
0
      bag->element[elem].local_key_id.size, 1);
1374
0
    if (result < 0) {
1375
0
      gnutls_assert();
1376
0
      return result;
1377
0
    }
1378
0
  }
1379
1380
0
  if (bag->element[elem].friendly_name != NULL) {
1381
0
    uint8_t *name;
1382
0
    int size, i;
1383
0
    const char *p;
1384
1385
    /* Add a new Attribute
1386
     */
1387
0
    result = asn1_write_value(c2, where, "NEW", 1);
1388
0
    if (result != ASN1_SUCCESS) {
1389
0
      gnutls_assert();
1390
0
      return _gnutls_asn2err(result);
1391
0
    }
1392
1393
    /* convert name to BMPString
1394
     */
1395
0
    size = strlen(bag->element[elem].friendly_name) * 2;
1396
0
    name = gnutls_malloc(size);
1397
1398
0
    if (name == NULL) {
1399
0
      gnutls_assert();
1400
0
      return GNUTLS_E_MEMORY_ERROR;
1401
0
    }
1402
1403
0
    p = bag->element[elem].friendly_name;
1404
0
    for (i = 0; i < size; i += 2) {
1405
0
      name[i] = 0;
1406
0
      name[i + 1] = *p;
1407
0
      p++;
1408
0
    }
1409
1410
0
    _gnutls_str_cpy(root, sizeof(root), where);
1411
0
    _gnutls_str_cat(root, sizeof(root), ".?LAST");
1412
1413
0
    result = _gnutls_x509_encode_and_write_attribute(
1414
0
      FRIENDLY_NAME_OID, c2, root, name, size, 1);
1415
1416
0
    gnutls_free(name);
1417
1418
0
    if (result < 0) {
1419
0
      gnutls_assert();
1420
0
      return result;
1421
0
    }
1422
0
  }
1423
1424
0
  return 0;
1425
0
}
1426
1427
/* Encodes the bag into a SafeContents structure, and puts the output in
1428
 * the given datum. Enc is set to non-zero if the data are encrypted;
1429
 */
1430
int _pkcs12_encode_safe_contents(gnutls_pkcs12_bag_t bag, asn1_node *contents,
1431
         int *enc)
1432
0
{
1433
0
  asn1_node c2 = NULL;
1434
0
  int result;
1435
0
  unsigned i;
1436
0
  const char *oid;
1437
1438
0
  if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc) {
1439
0
    *enc = 1;
1440
0
    return 0; /* ENCRYPTED BAG, do nothing. */
1441
0
  } else if (enc)
1442
0
    *enc = 0;
1443
1444
  /* Step 1. Create the SEQUENCE.
1445
   */
1446
1447
0
  if ((result = asn1_create_element(_gnutls_get_pkix(),
1448
0
            "PKIX1.pkcs-12-SafeContents", &c2)) !=
1449
0
      ASN1_SUCCESS) {
1450
0
    gnutls_assert();
1451
0
    result = _gnutls_asn2err(result);
1452
0
    goto cleanup;
1453
0
  }
1454
1455
0
  for (i = 0; i < bag->bag_elements; i++) {
1456
0
    oid = bag_to_oid(bag->element[i].type);
1457
0
    if (oid == NULL) {
1458
0
      gnutls_assert();
1459
0
      continue;
1460
0
    }
1461
1462
0
    result = asn1_write_value(c2, "", "NEW", 1);
1463
0
    if (result != ASN1_SUCCESS) {
1464
0
      gnutls_assert();
1465
0
      result = _gnutls_asn2err(result);
1466
0
      goto cleanup;
1467
0
    }
1468
1469
    /* Copy the bag type.
1470
     */
1471
0
    result = asn1_write_value(c2, "?LAST.bagId", oid, 1);
1472
0
    if (result != ASN1_SUCCESS) {
1473
0
      gnutls_assert();
1474
0
      result = _gnutls_asn2err(result);
1475
0
      goto cleanup;
1476
0
    }
1477
1478
    /* Set empty attributes
1479
     */
1480
0
    result = write_attributes(bag, i, c2, "?LAST.bagAttributes");
1481
0
    if (result < 0) {
1482
0
      gnutls_assert();
1483
0
      goto cleanup;
1484
0
    }
1485
1486
    /* Copy the Bag Value
1487
     */
1488
1489
0
    if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
1490
0
        bag->element[i].type == GNUTLS_BAG_SECRET ||
1491
0
        bag->element[i].type == GNUTLS_BAG_CRL) {
1492
0
      gnutls_datum_t tmp;
1493
1494
      /* in that case encode it to a CertBag or
1495
       * a CrlBag.
1496
       */
1497
1498
0
      result = _pkcs12_encode_crt_bag(bag->element[i].type,
1499
0
              &bag->element[i].data,
1500
0
              &tmp);
1501
1502
0
      if (result < 0) {
1503
0
        gnutls_assert();
1504
0
        goto cleanup;
1505
0
      }
1506
1507
0
      result = _gnutls_x509_write_value(c2, "?LAST.bagValue",
1508
0
                &tmp);
1509
1510
0
      _gnutls_free_datum(&tmp);
1511
1512
0
    } else {
1513
0
      result = _gnutls_x509_write_value(
1514
0
        c2, "?LAST.bagValue", &bag->element[i].data);
1515
0
    }
1516
1517
0
    if (result < 0) {
1518
0
      gnutls_assert();
1519
0
      goto cleanup;
1520
0
    }
1521
0
  }
1522
1523
  /* Encode the data and copy them into the datum
1524
   */
1525
0
  *contents = c2;
1526
1527
0
  return 0;
1528
1529
0
cleanup:
1530
0
  if (c2)
1531
0
    asn1_delete_structure(&c2);
1532
0
  return result;
1533
0
}
1534
1535
/* Checks if the extra_certs contain certificates that may form a chain
1536
 * with the first certificate in chain (it is expected that chain_len==1)
1537
 * and appends those in the chain.
1538
 */
1539
static int make_chain(gnutls_x509_crt_t **chain, unsigned int *chain_len,
1540
          gnutls_x509_crt_t **extra_certs,
1541
          unsigned int *extra_certs_len, unsigned int flags)
1542
45
{
1543
45
  unsigned int i;
1544
1545
45
  if (*chain_len != 1)
1546
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1547
1548
45
  i = 0;
1549
129
  while (i < *extra_certs_len) {
1550
    /* if it is an issuer but not a self-signed one */
1551
84
    if (gnutls_x509_crt_check_issuer((*chain)[*chain_len - 1],
1552
84
             (*extra_certs)[i]) != 0) {
1553
14
      if (!(flags & GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED) &&
1554
14
          gnutls_x509_crt_check_issuer(
1555
14
            (*extra_certs)[i], (*extra_certs)[i]) != 0)
1556
14
        goto skip;
1557
1558
0
      if (unlikely(INT_ADD_OVERFLOW(*chain_len, 1))) {
1559
0
        return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1560
0
      }
1561
1562
0
      *chain = _gnutls_reallocarray_fast(
1563
0
        *chain, ++(*chain_len), sizeof((*chain)[0]));
1564
0
      if (*chain == NULL) {
1565
0
        gnutls_assert();
1566
0
        return GNUTLS_E_MEMORY_ERROR;
1567
0
      }
1568
0
      (*chain)[*chain_len - 1] = (*extra_certs)[i];
1569
1570
0
      (*extra_certs)[i] =
1571
0
        (*extra_certs)[*extra_certs_len - 1];
1572
0
      (*extra_certs_len)--;
1573
1574
0
      i = 0;
1575
0
      continue;
1576
0
    }
1577
1578
84
  skip:
1579
84
    i++;
1580
84
  }
1581
45
  return 0;
1582
45
}
1583
1584
/**
1585
 * gnutls_pkcs12_simple_parse:
1586
 * @p12: A pkcs12 type
1587
 * @password: optional password used to decrypt the structure, bags and keys.
1588
 * @key: a structure to store the parsed private key.
1589
 * @chain: the corresponding to key certificate chain (may be %NULL)
1590
 * @chain_len: will be updated with the number of additional (may be %NULL)
1591
 * @extra_certs: optional pointer to receive an array of additional
1592
 *         certificates found in the PKCS12 structure (may be %NULL).
1593
 * @extra_certs_len: will be updated with the number of additional
1594
 *       certs (may be %NULL).
1595
 * @crl: an optional structure to store the parsed CRL (may be %NULL).
1596
 * @flags: should be zero or one of GNUTLS_PKCS12_SP_*
1597
 *
1598
 * This function parses a PKCS12 structure in @pkcs12 and extracts the
1599
 * private key, the corresponding certificate chain, any additional
1600
 * certificates and a CRL. The structures in @key, @chain @crl, and @extra_certs
1601
 * must not be initialized.
1602
 *
1603
 * The @extra_certs and @extra_certs_len parameters are optional
1604
 * and both may be set to %NULL. If either is non-%NULL, then both must
1605
 * be set. The value for @extra_certs is allocated
1606
 * using gnutls_malloc().
1607
 * 
1608
 * Encrypted PKCS12 bags and PKCS8 private keys are supported, but
1609
 * only with password based security and the same password for all
1610
 * operations.
1611
 *
1612
 * Note that a PKCS12 structure may contain many keys and/or certificates,
1613
 * and there is no way to identify which key/certificate pair you want.
1614
 * For this reason this function is useful for PKCS12 files that contain 
1615
 * only one key/certificate pair and/or one CRL.
1616
 *
1617
 * If the provided structure has encrypted fields but no password
1618
 * is provided then this function returns %GNUTLS_E_DECRYPTION_FAILED.
1619
 *
1620
 * Note that normally the chain constructed does not include self signed
1621
 * certificates, to comply with TLS' requirements. If, however, the flag 
1622
 * %GNUTLS_PKCS12_SP_INCLUDE_SELF_SIGNED is specified then
1623
 * self signed certificates will be included in the chain.
1624
 *
1625
 * Prior to using this function the PKCS #12 structure integrity must
1626
 * be verified using gnutls_pkcs12_verify_mac().
1627
 *
1628
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1629
 *   negative error value.
1630
 *
1631
 * Since: 3.1.0
1632
 **/
1633
int gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12, const char *password,
1634
             gnutls_x509_privkey_t *key,
1635
             gnutls_x509_crt_t **chain,
1636
             unsigned int *chain_len,
1637
             gnutls_x509_crt_t **extra_certs,
1638
             unsigned int *extra_certs_len,
1639
             gnutls_x509_crl_t *crl, unsigned int flags)
1640
6.61k
{
1641
6.61k
  gnutls_pkcs12_bag_t bag = NULL;
1642
6.61k
  gnutls_x509_crt_t *_extra_certs = NULL;
1643
6.61k
  unsigned int _extra_certs_len = 0;
1644
6.61k
  gnutls_x509_crt_t *_chain = NULL;
1645
6.61k
  unsigned int _chain_len = 0;
1646
6.61k
  int idx = 0;
1647
6.61k
  int ret;
1648
6.61k
  size_t cert_id_size = 0;
1649
6.61k
  size_t key_id_size = 0;
1650
6.61k
  uint8_t cert_id[20];
1651
6.61k
  uint8_t key_id[20];
1652
6.61k
  int privkey_ok = 0;
1653
6.61k
  unsigned int i;
1654
6.61k
  int elements_in_bag;
1655
1656
6.61k
  *key = NULL;
1657
1658
6.61k
  if (crl)
1659
6.61k
    *crl = NULL;
1660
1661
  /* find the first private key */
1662
8.03k
  for (;;) {
1663
8.03k
    ret = gnutls_pkcs12_bag_init(&bag);
1664
8.03k
    if (ret < 0) {
1665
0
      bag = NULL;
1666
0
      gnutls_assert();
1667
0
      goto done;
1668
0
    }
1669
1670
8.03k
    ret = gnutls_pkcs12_get_bag(p12, idx, bag);
1671
8.03k
    if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1672
348
      gnutls_pkcs12_bag_deinit(bag);
1673
348
      bag = NULL;
1674
348
      break;
1675
348
    }
1676
7.69k
    if (ret < 0) {
1677
984
      gnutls_assert();
1678
984
      goto done;
1679
984
    }
1680
1681
6.70k
    ret = gnutls_pkcs12_bag_get_type(bag, 0);
1682
6.70k
    if (ret < 0) {
1683
1
      gnutls_assert();
1684
1
      goto done;
1685
1
    }
1686
1687
6.70k
    if (ret == GNUTLS_BAG_ENCRYPTED) {
1688
1.89k
      if (password == NULL) {
1689
0
        ret = gnutls_assert_val(
1690
0
          GNUTLS_E_DECRYPTION_FAILED);
1691
0
        goto done;
1692
0
      }
1693
1694
1.89k
      ret = gnutls_pkcs12_bag_decrypt(bag, password);
1695
1.89k
      if (ret < 0) {
1696
569
        gnutls_assert();
1697
569
        goto done;
1698
569
      }
1699
1.89k
    }
1700
1701
6.13k
    elements_in_bag = gnutls_pkcs12_bag_get_count(bag);
1702
6.13k
    if (elements_in_bag < 0) {
1703
0
      gnutls_assert();
1704
0
      goto done;
1705
0
    }
1706
1707
9.31k
    for (i = 0; i < (unsigned)elements_in_bag; i++) {
1708
6.25k
      int type;
1709
6.25k
      gnutls_datum_t data;
1710
1711
6.25k
      type = gnutls_pkcs12_bag_get_type(bag, i);
1712
6.25k
      if (type < 0) {
1713
0
        gnutls_assert();
1714
0
        goto done;
1715
0
      }
1716
1717
6.25k
      ret = gnutls_pkcs12_bag_get_data(bag, i, &data);
1718
6.25k
      if (ret < 0) {
1719
0
        gnutls_assert();
1720
0
        goto done;
1721
0
      }
1722
1723
6.25k
      switch (type) {
1724
4.70k
      case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1725
4.70k
        if (password == NULL) {
1726
0
          ret = gnutls_assert_val(
1727
0
            GNUTLS_E_DECRYPTION_FAILED);
1728
0
          goto done;
1729
0
        }
1730
1731
4.70k
        FALLTHROUGH;
1732
4.71k
      case GNUTLS_BAG_PKCS8_KEY:
1733
4.71k
        if (*key != NULL) { /* too simple to continue */
1734
0
          gnutls_assert();
1735
0
          break;
1736
0
        }
1737
1738
4.71k
        ret = gnutls_x509_privkey_init(key);
1739
4.71k
        if (ret < 0) {
1740
0
          gnutls_assert();
1741
0
          goto done;
1742
0
        }
1743
1744
4.71k
        ret = gnutls_x509_privkey_import_pkcs8(
1745
4.71k
          *key, &data, GNUTLS_X509_FMT_DER,
1746
4.71k
          password,
1747
4.71k
          type == GNUTLS_BAG_PKCS8_KEY ?
1748
7
            GNUTLS_PKCS_PLAIN :
1749
4.71k
            0);
1750
4.71k
        if (ret < 0) {
1751
3.06k
          gnutls_assert();
1752
3.06k
          goto done;
1753
3.06k
        }
1754
1755
1.64k
        key_id_size = sizeof(key_id);
1756
1.64k
        ret = gnutls_x509_privkey_get_key_id(
1757
1.64k
          *key, 0, key_id, &key_id_size);
1758
1.64k
        if (ret < 0) {
1759
1
          gnutls_assert();
1760
1
          goto done;
1761
1
        }
1762
1763
1.64k
        privkey_ok = 1; /* break */
1764
1.64k
        break;
1765
1.53k
      default:
1766
1.53k
        break;
1767
6.25k
      }
1768
6.25k
    }
1769
1770
3.06k
    idx++;
1771
3.06k
    gnutls_pkcs12_bag_deinit(bag);
1772
3.06k
    bag = NULL;
1773
1774
3.06k
    if (privkey_ok != 0) /* private key was found */
1775
1.64k
      break;
1776
3.06k
  }
1777
1778
1.99k
  if (privkey_ok == 0) { /* no private key */
1779
348
    gnutls_assert();
1780
348
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1781
348
  }
1782
1783
  /* now find the corresponding certificate 
1784
   */
1785
1.64k
  idx = 0;
1786
1.64k
  bag = NULL;
1787
3.24k
  for (;;) {
1788
3.24k
    ret = gnutls_pkcs12_bag_init(&bag);
1789
3.24k
    if (ret < 0) {
1790
0
      bag = NULL;
1791
0
      gnutls_assert();
1792
0
      goto done;
1793
0
    }
1794
1795
3.24k
    ret = gnutls_pkcs12_get_bag(p12, idx, bag);
1796
3.24k
    if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1797
1.14k
      gnutls_pkcs12_bag_deinit(bag);
1798
1.14k
      bag = NULL;
1799
1.14k
      break;
1800
1.14k
    }
1801
2.10k
    if (ret < 0) {
1802
0
      gnutls_assert();
1803
0
      goto done;
1804
0
    }
1805
1806
2.10k
    ret = gnutls_pkcs12_bag_get_type(bag, 0);
1807
2.10k
    if (ret < 0) {
1808
0
      gnutls_assert();
1809
0
      goto done;
1810
0
    }
1811
1812
2.10k
    if (ret == GNUTLS_BAG_ENCRYPTED) {
1813
959
      ret = gnutls_pkcs12_bag_decrypt(bag, password);
1814
959
      if (ret < 0) {
1815
0
        gnutls_assert();
1816
0
        goto done;
1817
0
      }
1818
959
    }
1819
1820
2.10k
    elements_in_bag = gnutls_pkcs12_bag_get_count(bag);
1821
2.10k
    if (elements_in_bag < 0) {
1822
0
      gnutls_assert();
1823
0
      goto done;
1824
0
    }
1825
1826
3.69k
    for (i = 0; i < (unsigned)elements_in_bag; i++) {
1827
2.10k
      int type;
1828
2.10k
      gnutls_datum_t data;
1829
2.10k
      gnutls_x509_crt_t this_cert;
1830
1831
2.10k
      type = gnutls_pkcs12_bag_get_type(bag, i);
1832
2.10k
      if (type < 0) {
1833
0
        gnutls_assert();
1834
0
        goto done;
1835
0
      }
1836
1837
2.10k
      ret = gnutls_pkcs12_bag_get_data(bag, i, &data);
1838
2.10k
      if (ret < 0) {
1839
0
        gnutls_assert();
1840
0
        goto done;
1841
0
      }
1842
1843
2.10k
      switch (type) {
1844
762
      case GNUTLS_BAG_CERTIFICATE:
1845
762
        ret = gnutls_x509_crt_init(&this_cert);
1846
762
        if (ret < 0) {
1847
0
          gnutls_assert();
1848
0
          goto done;
1849
0
        }
1850
1851
762
        ret = gnutls_x509_crt_import(
1852
762
          this_cert, &data, GNUTLS_X509_FMT_DER);
1853
762
        if (ret < 0) {
1854
405
          gnutls_assert();
1855
405
          gnutls_x509_crt_deinit(this_cert);
1856
405
          this_cert = NULL;
1857
405
          goto done;
1858
405
        }
1859
1860
        /* check if the key id match */
1861
357
        cert_id_size = sizeof(cert_id);
1862
357
        ret = gnutls_x509_crt_get_key_id(
1863
357
          this_cert, 0, cert_id, &cert_id_size);
1864
357
        if (ret < 0) {
1865
91
          gnutls_assert();
1866
91
          gnutls_x509_crt_deinit(this_cert);
1867
91
          this_cert = NULL;
1868
91
          goto done;
1869
91
        }
1870
1871
266
        if (!memeq(cert_id, key_id,
1872
266
             cert_id_size)) { /* they don't match - skip the certificate */
1873
210
          if (unlikely(INT_ADD_OVERFLOW(
1874
210
                _extra_certs_len, 1))) {
1875
0
            ret = gnutls_assert_val(
1876
0
              GNUTLS_E_MEMORY_ERROR);
1877
0
            goto done;
1878
0
          }
1879
1880
210
          _extra_certs = _gnutls_reallocarray_fast(
1881
210
            _extra_certs,
1882
210
            ++_extra_certs_len,
1883
210
            sizeof(_extra_certs[0]));
1884
210
          if (!_extra_certs) {
1885
0
            gnutls_assert();
1886
0
            ret = GNUTLS_E_MEMORY_ERROR;
1887
0
            goto done;
1888
0
          }
1889
210
          _extra_certs[_extra_certs_len - 1] =
1890
210
            this_cert;
1891
210
          this_cert = NULL;
1892
210
        } else {
1893
56
          if (chain && _chain_len == 0) {
1894
56
            _chain = gnutls_malloc(
1895
56
              sizeof(_chain[0]) *
1896
56
              (++_chain_len));
1897
56
            if (!_chain) {
1898
0
              gnutls_assert();
1899
0
              ret = GNUTLS_E_MEMORY_ERROR;
1900
0
              goto done;
1901
0
            }
1902
56
            _chain[_chain_len - 1] =
1903
56
              this_cert;
1904
56
            this_cert = NULL;
1905
56
          } else {
1906
0
            gnutls_x509_crt_deinit(
1907
0
              this_cert);
1908
0
            this_cert = NULL;
1909
0
          }
1910
56
        }
1911
266
        break;
1912
1913
266
      case GNUTLS_BAG_CRL:
1914
10
        if (crl == NULL || *crl != NULL) {
1915
0
          gnutls_assert();
1916
0
          break;
1917
0
        }
1918
1919
10
        ret = gnutls_x509_crl_init(crl);
1920
10
        if (ret < 0) {
1921
0
          gnutls_assert();
1922
0
          goto done;
1923
0
        }
1924
1925
10
        ret = gnutls_x509_crl_import(
1926
10
          *crl, &data, GNUTLS_X509_FMT_DER);
1927
10
        if (ret < 0) {
1928
8
          gnutls_assert();
1929
8
          gnutls_x509_crl_deinit(*crl);
1930
8
          *crl = NULL;
1931
8
          goto done;
1932
8
        }
1933
2
        break;
1934
1935
2
      case GNUTLS_BAG_ENCRYPTED:
1936
        /* XXX Bother to recurse one level down?  Unlikely to
1937
           use the same password anyway. */
1938
0
      case GNUTLS_BAG_EMPTY:
1939
1.32k
      default:
1940
1.32k
        break;
1941
2.10k
      }
1942
2.10k
    }
1943
1944
1.59k
    idx++;
1945
1.59k
    gnutls_pkcs12_bag_deinit(bag);
1946
1.59k
    bag = NULL;
1947
1.59k
  }
1948
1949
1.14k
  if (chain != NULL) {
1950
1.14k
    if (_chain_len != 1) {
1951
1.09k
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1952
1.09k
      goto done;
1953
1.09k
    }
1954
1955
45
    ret = make_chain(&_chain, &_chain_len, &_extra_certs,
1956
45
         &_extra_certs_len, flags);
1957
45
    if (ret < 0) {
1958
0
      gnutls_assert();
1959
0
      goto done;
1960
0
    }
1961
45
  }
1962
1963
45
  ret = 0;
1964
1965
6.26k
done:
1966
6.26k
  if (bag)
1967
5.12k
    gnutls_pkcs12_bag_deinit(bag);
1968
1969
6.26k
  if (ret < 0) {
1970
6.22k
    if (*key) {
1971
4.66k
      gnutls_x509_privkey_deinit(*key);
1972
4.66k
      *key = NULL;
1973
4.66k
    }
1974
6.22k
    if (crl != NULL && *crl != NULL) {
1975
1
      gnutls_x509_crl_deinit(*crl);
1976
1
      *crl = NULL;
1977
1
    }
1978
6.22k
    if (_extra_certs_len && _extra_certs != NULL) {
1979
195
      for (i = 0; i < _extra_certs_len; i++)
1980
126
        gnutls_x509_crt_deinit(_extra_certs[i]);
1981
69
      gnutls_free(_extra_certs);
1982
69
    }
1983
6.22k
    if (_chain_len && _chain != NULL) {
1984
22
      for (i = 0; i < _chain_len; i++)
1985
11
        gnutls_x509_crt_deinit(_chain[i]);
1986
11
      gnutls_free(_chain);
1987
11
    }
1988
1989
6.22k
    return ret;
1990
6.22k
  }
1991
1992
45
  if (extra_certs && _extra_certs_len > 0) {
1993
36
    *extra_certs = _extra_certs;
1994
36
    *extra_certs_len = _extra_certs_len;
1995
36
  } else {
1996
9
    if (extra_certs) {
1997
9
      *extra_certs = NULL;
1998
9
      *extra_certs_len = 0;
1999
9
    }
2000
9
    for (i = 0; i < _extra_certs_len; i++)
2001
0
      gnutls_x509_crt_deinit(_extra_certs[i]);
2002
9
    gnutls_free(_extra_certs);
2003
9
  }
2004
2005
45
  if (chain != NULL) {
2006
45
    *chain = _chain;
2007
45
    *chain_len = _chain_len;
2008
45
  }
2009
2010
45
  return ret;
2011
6.26k
}
2012
2013
/**
2014
 * gnutls_pkcs12_mac_info:
2015
 * @pkcs12: A pkcs12 type
2016
 * @mac: the MAC algorithm used as %gnutls_mac_algorithm_t
2017
 * @salt: the salt used for string to key (if non-NULL then @salt_size initially holds its size)
2018
 * @salt_size: string to key salt size
2019
 * @iter_count: string to key iteration count
2020
 * @oid: if non-NULL it will contain an allocated null-terminated variable with the OID
2021
 *
2022
 * This function will provide information on the MAC algorithm used
2023
 * in a PKCS #12 structure. If the structure algorithms
2024
 * are unknown the code %GNUTLS_E_UNKNOWN_HASH_ALGORITHM will be returned,
2025
 * and only @oid, will be set. That is, @oid will be set on structures
2026
 * with a MAC whether supported or not. It must be deinitialized using gnutls_free().
2027
 * The other variables are only set on supported structures.
2028
 *
2029
 * Returns: %GNUTLS_E_INVALID_REQUEST if the provided structure doesn't contain a MAC,
2030
 *  %GNUTLS_E_UNKNOWN_HASH_ALGORITHM if the structure's MAC isn't supported, or
2031
 *  another negative error code in case of a failure. Zero on success.
2032
 **/
2033
int gnutls_pkcs12_mac_info(gnutls_pkcs12_t pkcs12, unsigned int *mac,
2034
         void *salt, unsigned int *salt_size,
2035
         unsigned int *iter_count, char **oid)
2036
0
{
2037
0
  int ret;
2038
0
  gnutls_datum_t tmp = { NULL, 0 }, dsalt = { NULL, 0 };
2039
0
  gnutls_mac_algorithm_t algo;
2040
2041
0
  if (oid)
2042
0
    *oid = NULL;
2043
2044
0
  if (pkcs12 == NULL) {
2045
0
    gnutls_assert();
2046
0
    return GNUTLS_E_INVALID_REQUEST;
2047
0
  }
2048
2049
0
  ret = _gnutls_x509_read_value(
2050
0
    pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm", &tmp);
2051
0
  if (ret < 0) {
2052
0
    gnutls_assert();
2053
0
    return GNUTLS_E_INVALID_REQUEST;
2054
0
  }
2055
2056
0
  if (oid) {
2057
0
    *oid = (char *)tmp.data;
2058
0
  }
2059
2060
0
  if (streq((char *)tmp.data, PBMAC1_OID)) {
2061
0
    algo = GNUTLS_MAC_PBMAC1;
2062
0
  } else {
2063
0
    algo = DIG_TO_MAC(gnutls_oid_to_digest((char *)tmp.data));
2064
0
  }
2065
0
  if (algo == GNUTLS_MAC_UNKNOWN || mac_to_entry(algo) == NULL) {
2066
0
    gnutls_assert();
2067
0
    return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
2068
0
  }
2069
2070
0
  if (oid) {
2071
0
    tmp.data = NULL;
2072
0
  }
2073
2074
0
  if (mac) {
2075
0
    *mac = algo;
2076
0
  }
2077
2078
0
  if (iter_count) {
2079
0
    ret = _gnutls_x509_read_uint(pkcs12->pkcs12,
2080
0
               "macData.iterations", iter_count);
2081
0
    if (ret < 0) {
2082
0
      *iter_count = 1; /* the default */
2083
0
    }
2084
0
  }
2085
2086
0
  if (salt) {
2087
    /* Read the salt from the structure.
2088
     */
2089
0
    ret = _gnutls_x509_read_null_value(pkcs12->pkcs12,
2090
0
               "macData.macSalt", &dsalt);
2091
0
    if (ret < 0) {
2092
0
      gnutls_assert();
2093
0
      goto cleanup;
2094
0
    }
2095
2096
0
    if (*salt_size >= (unsigned)dsalt.size) {
2097
0
      *salt_size = dsalt.size;
2098
0
      if (dsalt.size > 0)
2099
0
        memcpy(salt, dsalt.data, dsalt.size);
2100
0
    } else {
2101
0
      *salt_size = dsalt.size;
2102
0
      ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
2103
0
      goto cleanup;
2104
0
    }
2105
0
  }
2106
2107
0
  ret = 0;
2108
0
cleanup:
2109
0
  _gnutls_free_datum(&tmp);
2110
0
  _gnutls_free_datum(&dsalt);
2111
0
  return ret;
2112
0
}