LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - pkcs12.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 744 961 77.4 %
Date: 2020-10-30 04:50:48 Functions: 21 23 91.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14