Coverage Report

Created: 2024-07-23 07:36

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