LCOV - code coverage report
Current view: top level - builds/gnutls/coverage/gnutls-git/lib/x509 - pkcs12_bag.c (source / functions) Hit Total Coverage
Test: GnuTLS-3.6.14 Code Coverage Lines: 204 352 58.0 %
Date: 2020-10-30 04:50:48 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2003-2014 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2014 Red Hat
       4             :  *
       5             :  * Author: Nikos Mavrogiannopoulos
       6             :  *
       7             :  * This file is part of GnuTLS.
       8             :  *
       9             :  * The GnuTLS is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public License
      11             :  * as published by the Free Software Foundation; either version 2.1 of
      12             :  * the License, or (at your option) any later version.
      13             :  *
      14             :  * This library is distributed in the hope that it will be useful, but
      15             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public License
      20             :  * along with this program.  If not, see <https://www.gnu.org/licenses/>
      21             :  *
      22             :  */
      23             : 
      24             : /* Functions that relate on PKCS12 Bag packet parsing.
      25             :  */
      26             : 
      27             : #include "gnutls_int.h"
      28             : 
      29             : #include <datum.h>
      30             : #include <global.h>
      31             : #include "errors.h"
      32             : #include <common.h>
      33             : #include "x509_int.h"
      34             : #include "pkcs7_int.h"
      35             : 
      36             : /**
      37             :  * gnutls_pkcs12_bag_init:
      38             :  * @bag: A pointer to the type to be initialized
      39             :  *
      40             :  * This function will initialize a PKCS12 bag structure. PKCS12 Bags
      41             :  * usually contain private keys, lists of X.509 Certificates and X.509
      42             :  * Certificate revocation lists.
      43             :  *
      44             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
      45             :  *   negative error value.
      46             :  **/
      47         751 : int gnutls_pkcs12_bag_init(gnutls_pkcs12_bag_t * bag)
      48             : {
      49         751 :         *bag = gnutls_calloc(1, sizeof(gnutls_pkcs12_bag_int));
      50             : 
      51         751 :         if (*bag) {
      52         751 :                 return 0;       /* success */
      53             :         }
      54             :         return GNUTLS_E_MEMORY_ERROR;
      55             : }
      56             : 
      57         765 : static inline void _pkcs12_bag_free_data(gnutls_pkcs12_bag_t bag)
      58             : {
      59         765 :         unsigned i;
      60             : 
      61        1537 :         for (i = 0; i < bag->bag_elements; i++) {
      62         772 :                 _gnutls_free_datum(&bag->element[i].data);
      63         772 :                 _gnutls_free_datum(&bag->element[i].local_key_id);
      64         772 :                 gnutls_free(bag->element[i].friendly_name);
      65         772 :                 bag->element[i].type = 0;
      66             :         }
      67             : 
      68         765 : }
      69             : 
      70             : 
      71             : /**
      72             :  * gnutls_pkcs12_bag_deinit:
      73             :  * @bag: A pointer to the type to be initialized
      74             :  *
      75             :  * This function will deinitialize a PKCS12 Bag structure.
      76             :  **/
      77         751 : void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag_t bag)
      78             : {
      79         751 :         if (!bag)
      80             :                 return;
      81             : 
      82         751 :         _pkcs12_bag_free_data(bag);
      83             : 
      84         751 :         gnutls_free(bag);
      85             : }
      86             : 
      87             : /**
      88             :  * gnutls_pkcs12_bag_get_type:
      89             :  * @bag: The bag
      90             :  * @indx: The element of the bag to get the type
      91             :  *
      92             :  * This function will return the bag's type.
      93             :  *
      94             :  * Returns: On error a negative error value or one of the #gnutls_pkcs12_bag_type_t enumerations.
      95             :  **/
      96             : int
      97        1319 : gnutls_pkcs12_bag_get_type(gnutls_pkcs12_bag_t bag, unsigned indx)
      98             : {
      99        1319 :         if (bag == NULL) {
     100           0 :                 gnutls_assert();
     101           0 :                 return GNUTLS_E_INVALID_REQUEST;
     102             :         }
     103             : 
     104        1319 :         if (indx >= bag->bag_elements)
     105             :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     106        1318 :         return bag->element[indx].type;
     107             : }
     108             : 
     109             : /**
     110             :  * gnutls_pkcs12_bag_get_count:
     111             :  * @bag: The bag
     112             :  *
     113             :  * This function will return the number of the elements within the bag.
     114             :  *
     115             :  * Returns: Number of elements in bag, or an negative error code on
     116             :  *   error.
     117             :  **/
     118         693 : int gnutls_pkcs12_bag_get_count(gnutls_pkcs12_bag_t bag)
     119             : {
     120         693 :         if (bag == NULL) {
     121           0 :                 gnutls_assert();
     122           0 :                 return GNUTLS_E_INVALID_REQUEST;
     123             :         }
     124             : 
     125         693 :         return bag->bag_elements;
     126             : }
     127             : 
     128             : /**
     129             :  * gnutls_pkcs12_bag_get_data:
     130             :  * @bag: The bag
     131             :  * @indx: The element of the bag to get the data from
     132             :  * @data: where the bag's data will be. Should be treated as constant.
     133             :  *
     134             :  * This function will return the bag's data. The data is a constant
     135             :  * that is stored into the bag.  Should not be accessed after the bag
     136             :  * is deleted.
     137             :  *
     138             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     139             :  *   negative error value.
     140             :  **/
     141             : int
     142         687 : gnutls_pkcs12_bag_get_data(gnutls_pkcs12_bag_t bag, unsigned indx,
     143             :                            gnutls_datum_t * data)
     144             : {
     145         687 :         if (bag == NULL) {
     146           0 :                 gnutls_assert();
     147           0 :                 return GNUTLS_E_INVALID_REQUEST;
     148             :         }
     149             : 
     150         687 :         if (indx >= bag->bag_elements)
     151             :                 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
     152             : 
     153         687 :         data->data = bag->element[indx].data.data;
     154         687 :         data->size = bag->element[indx].data.size;
     155             : 
     156         687 :         return 0;
     157             : }
     158             : 
     159             : #define X509_CERT_OID "1.2.840.113549.1.9.22.1"
     160             : #define X509_CRL_OID  "1.2.840.113549.1.9.23.1"
     161             : #define RANDOM_NONCE_OID "1.2.840.113549.1.9.25.3"
     162             : 
     163             : int
     164         362 : _pkcs12_decode_crt_bag(gnutls_pkcs12_bag_type_t type,
     165             :                        const gnutls_datum_t * in, gnutls_datum_t * out)
     166             : {
     167         362 :         int ret;
     168         362 :         ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
     169             : 
     170         362 :         switch (type) {
     171         344 :         case GNUTLS_BAG_CERTIFICATE:
     172         344 :                 if ((ret = asn1_create_element(_gnutls_get_pkix(),
     173             :                                                "PKIX1.pkcs-12-CertBag",
     174             :                                                &c2)) != ASN1_SUCCESS) {
     175           0 :                         gnutls_assert();
     176           0 :                         ret = _gnutls_asn2err(ret);
     177           0 :                         goto cleanup;
     178             :                 }
     179             : 
     180         344 :                 ret = asn1_der_decoding(&c2, in->data, in->size, NULL);
     181         344 :                 if (ret != ASN1_SUCCESS) {
     182           1 :                         gnutls_assert();
     183           1 :                         ret = _gnutls_asn2err(ret);
     184           1 :                         goto cleanup;
     185             :                 }
     186             : 
     187         343 :                 ret =
     188         343 :                     _gnutls_x509_read_string(c2, "certValue", out,
     189             :                                              ASN1_ETYPE_OCTET_STRING, 1);
     190         343 :                 if (ret < 0) {
     191           1 :                         gnutls_assert();
     192           1 :                         goto cleanup;
     193             :                 }
     194             :                 break;
     195             : 
     196          17 :         case GNUTLS_BAG_CRL:
     197          17 :                 if ((ret = asn1_create_element(_gnutls_get_pkix(),
     198             :                                                "PKIX1.pkcs-12-CRLBag",
     199             :                                                &c2)) != ASN1_SUCCESS) {
     200           0 :                         gnutls_assert();
     201           0 :                         ret = _gnutls_asn2err(ret);
     202           0 :                         goto cleanup;
     203             :                 }
     204             : 
     205          17 :                 ret = asn1_der_decoding(&c2, in->data, in->size, NULL);
     206          17 :                 if (ret != ASN1_SUCCESS) {
     207           1 :                         gnutls_assert();
     208           1 :                         ret = _gnutls_asn2err(ret);
     209           1 :                         goto cleanup;
     210             :                 }
     211             : 
     212          16 :                 ret =
     213          16 :                     _gnutls_x509_read_string(c2, "crlValue", out,
     214             :                                              ASN1_ETYPE_OCTET_STRING, 1);
     215          16 :                 if (ret < 0) {
     216           0 :                         gnutls_assert();
     217           0 :                         goto cleanup;
     218             :                 }
     219             :                 break;
     220             : 
     221           1 :         case GNUTLS_BAG_SECRET:
     222           1 :                 if ((ret = asn1_create_element(_gnutls_get_pkix(),
     223             :                                                "PKIX1.pkcs-12-SecretBag",
     224             :                                                &c2)) != ASN1_SUCCESS) {
     225           0 :                         gnutls_assert();
     226           0 :                         ret = _gnutls_asn2err(ret);
     227           0 :                         goto cleanup;
     228             :                 }
     229             : 
     230           1 :                 ret = asn1_der_decoding(&c2, in->data, in->size, NULL);
     231           1 :                 if (ret != ASN1_SUCCESS) {
     232           1 :                         gnutls_assert();
     233           1 :                         ret = _gnutls_asn2err(ret);
     234           1 :                         goto cleanup;
     235             :                 }
     236             : 
     237           0 :                 ret =
     238           0 :                     _gnutls_x509_read_string(c2, "secretValue", out,
     239             :                                              ASN1_ETYPE_OCTET_STRING, 1);
     240           0 :                 if (ret < 0) {
     241           0 :                         gnutls_assert();
     242           0 :                         goto cleanup;
     243             :                 }
     244             :                 break;
     245             : 
     246           0 :         default:
     247           0 :                 gnutls_assert();
     248           0 :                 asn1_delete_structure(&c2);
     249           0 :                 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
     250             :         }
     251             : 
     252         358 :         asn1_delete_structure(&c2);
     253             : 
     254         358 :         return 0;
     255             : 
     256             : 
     257           4 :       cleanup:
     258             : 
     259           4 :         asn1_delete_structure(&c2);
     260           4 :         return ret;
     261             : }
     262             : 
     263             : 
     264             : int
     265          14 : _pkcs12_encode_crt_bag(gnutls_pkcs12_bag_type_t type,
     266             :                        const gnutls_datum_t * raw, gnutls_datum_t * out)
     267             : {
     268          14 :         int ret;
     269          14 :         ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
     270             : 
     271          14 :         switch (type) {
     272          13 :         case GNUTLS_BAG_CERTIFICATE:
     273          13 :                 if ((ret = asn1_create_element(_gnutls_get_pkix(),
     274             :                                                "PKIX1.pkcs-12-CertBag",
     275             :                                                &c2)) != ASN1_SUCCESS) {
     276           0 :                         gnutls_assert();
     277           0 :                         ret = _gnutls_asn2err(ret);
     278           0 :                         goto cleanup;
     279             :                 }
     280             : 
     281          13 :                 ret = asn1_write_value(c2, "certId", X509_CERT_OID, 1);
     282          13 :                 if (ret != ASN1_SUCCESS) {
     283           0 :                         gnutls_assert();
     284           0 :                         ret = _gnutls_asn2err(ret);
     285           0 :                         goto cleanup;
     286             :                 }
     287             : 
     288          13 :                 ret =
     289          13 :                     _gnutls_x509_write_string(c2, "certValue", raw,
     290             :                                               ASN1_ETYPE_OCTET_STRING);
     291          13 :                 if (ret < 0) {
     292           0 :                         gnutls_assert();
     293           0 :                         goto cleanup;
     294             :                 }
     295             :                 break;
     296             : 
     297           1 :         case GNUTLS_BAG_CRL:
     298           1 :                 if ((ret = asn1_create_element(_gnutls_get_pkix(),
     299             :                                                "PKIX1.pkcs-12-CRLBag",
     300             :                                                &c2)) != ASN1_SUCCESS) {
     301           0 :                         gnutls_assert();
     302           0 :                         ret = _gnutls_asn2err(ret);
     303           0 :                         goto cleanup;
     304             :                 }
     305             : 
     306           1 :                 ret = asn1_write_value(c2, "crlId", X509_CRL_OID, 1);
     307           1 :                 if (ret != ASN1_SUCCESS) {
     308           0 :                         gnutls_assert();
     309           0 :                         ret = _gnutls_asn2err(ret);
     310           0 :                         goto cleanup;
     311             :                 }
     312             : 
     313           1 :                 ret =
     314           1 :                     _gnutls_x509_write_string(c2, "crlValue", raw,
     315             :                                               ASN1_ETYPE_OCTET_STRING);
     316           1 :                 if (ret < 0) {
     317           0 :                         gnutls_assert();
     318           0 :                         goto cleanup;
     319             :                 }
     320             :                 break;
     321             : 
     322           0 :         case GNUTLS_BAG_SECRET:
     323           0 :                 if ((ret = asn1_create_element(_gnutls_get_pkix(),
     324             :                                                "PKIX1.pkcs-12-SecretBag",
     325             :                                                &c2)) != ASN1_SUCCESS) {
     326           0 :                         gnutls_assert();
     327           0 :                         ret = _gnutls_asn2err(ret);
     328           0 :                         goto cleanup;
     329             :                 }
     330             : 
     331           0 :                 ret =
     332           0 :                     asn1_write_value(c2, "secretTypeId", RANDOM_NONCE_OID,
     333             :                                      1);
     334           0 :                 if (ret != ASN1_SUCCESS) {
     335           0 :                         gnutls_assert();
     336           0 :                         ret = _gnutls_asn2err(ret);
     337           0 :                         goto cleanup;
     338             :                 }
     339             : 
     340           0 :                 ret =
     341           0 :                     _gnutls_x509_write_string(c2, "secretValue", raw,
     342             :                                               ASN1_ETYPE_OCTET_STRING);
     343           0 :                 if (ret < 0) {
     344           0 :                         gnutls_assert();
     345           0 :                         goto cleanup;
     346             :                 }
     347             :                 break;
     348             : 
     349           0 :         default:
     350           0 :                 gnutls_assert();
     351           0 :                 asn1_delete_structure(&c2);
     352           0 :                 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
     353             :         }
     354             : 
     355          14 :         ret = _gnutls_x509_der_encode(c2, "", out, 0);
     356             : 
     357          14 :         if (ret < 0) {
     358           0 :                 gnutls_assert();
     359           0 :                 goto cleanup;
     360             :         }
     361             : 
     362          14 :         asn1_delete_structure(&c2);
     363             : 
     364          14 :         return 0;
     365             : 
     366             : 
     367           0 :       cleanup:
     368             : 
     369           0 :         asn1_delete_structure(&c2);
     370           0 :         return ret;
     371             : }
     372             : 
     373             : 
     374             : /**
     375             :  * gnutls_pkcs12_bag_set_data:
     376             :  * @bag: The bag
     377             :  * @type: The data's type
     378             :  * @data: the data to be copied.
     379             :  *
     380             :  * This function will insert the given data of the given type into
     381             :  * the bag.
     382             :  *
     383             :  * Returns: the index of the added bag on success, or a negative
     384             :  * value on error.
     385             :  **/
     386             : int
     387          20 : gnutls_pkcs12_bag_set_data(gnutls_pkcs12_bag_t bag,
     388             :                            gnutls_pkcs12_bag_type_t type,
     389             :                            const gnutls_datum_t * data)
     390             : {
     391          20 :         int ret;
     392          20 :         if (bag == NULL) {
     393           0 :                 gnutls_assert();
     394           0 :                 return GNUTLS_E_INVALID_REQUEST;
     395             :         }
     396             : 
     397          20 :         if (bag->bag_elements == MAX_BAG_ELEMENTS - 1) {
     398           0 :                 gnutls_assert();
     399             :                 /* bag is full */
     400           0 :                 return GNUTLS_E_MEMORY_ERROR;
     401             :         }
     402             : 
     403          20 :         if (bag->bag_elements == 1) {
     404             :                 /* A bag with a key or an encrypted bag, must have
     405             :                  * only one element.
     406             :                  */
     407             : 
     408           0 :                 if (bag->element[0].type == GNUTLS_BAG_PKCS8_KEY ||
     409             :                     bag->element[0].type == GNUTLS_BAG_PKCS8_ENCRYPTED_KEY
     410           0 :                     || bag->element[0].type == GNUTLS_BAG_ENCRYPTED) {
     411           0 :                         gnutls_assert();
     412           0 :                         return GNUTLS_E_INVALID_REQUEST;
     413             :                 }
     414             :         }
     415             : 
     416          20 :         ret =
     417          40 :             _gnutls_set_datum(&bag->element[bag->bag_elements].data,
     418          20 :                               data->data, data->size);
     419             : 
     420          20 :         if (ret < 0) {
     421           0 :                 gnutls_assert();
     422           0 :                 return ret;
     423             :         }
     424             : 
     425          20 :         bag->element[bag->bag_elements].type = type;
     426             : 
     427          20 :         bag->bag_elements++;
     428             : 
     429          20 :         return bag->bag_elements - 1;
     430             : }
     431             : 
     432             : /**
     433             :  * gnutls_pkcs12_bag_set_crt:
     434             :  * @bag: The bag
     435             :  * @crt: the certificate to be copied.
     436             :  *
     437             :  * This function will insert the given certificate into the
     438             :  * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
     439             :  *
     440             :  * Returns: the index of the added bag on success, or a negative
     441             :  * value on failure.
     442             :  **/
     443             : int
     444          13 : gnutls_pkcs12_bag_set_crt(gnutls_pkcs12_bag_t bag, gnutls_x509_crt_t crt)
     445             : {
     446          13 :         int ret;
     447          13 :         gnutls_datum_t data;
     448             : 
     449          13 :         if (bag == NULL) {
     450           0 :                 gnutls_assert();
     451           0 :                 return GNUTLS_E_INVALID_REQUEST;
     452             :         }
     453             : 
     454          13 :         ret = _gnutls_x509_der_encode(crt->cert, "", &data, 0);
     455          13 :         if (ret < 0) {
     456           0 :                 gnutls_assert();
     457           0 :                 return ret;
     458             :         }
     459             : 
     460          13 :         ret =
     461          13 :             gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_CERTIFICATE, &data);
     462             : 
     463          13 :         _gnutls_free_datum(&data);
     464             : 
     465          13 :         return ret;
     466             : }
     467             : 
     468             : /**
     469             :  * gnutls_pkcs12_bag_set_crl:
     470             :  * @bag: The bag
     471             :  * @crl: the CRL to be copied.
     472             :  *
     473             :  * This function will insert the given CRL into the
     474             :  * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
     475             :  *
     476             :  * Returns: the index of the added bag on success, or a negative error code
     477             :  * on failure.
     478             :  **/
     479             : int
     480           1 : gnutls_pkcs12_bag_set_crl(gnutls_pkcs12_bag_t bag, gnutls_x509_crl_t crl)
     481             : {
     482           1 :         int ret;
     483           1 :         gnutls_datum_t data;
     484             : 
     485             : 
     486           1 :         if (bag == NULL) {
     487           0 :                 gnutls_assert();
     488           0 :                 return GNUTLS_E_INVALID_REQUEST;
     489             :         }
     490             : 
     491           1 :         ret = _gnutls_x509_der_encode(crl->crl, "", &data, 0);
     492           1 :         if (ret < 0) {
     493           0 :                 gnutls_assert();
     494           0 :                 return ret;
     495             :         }
     496             : 
     497           1 :         ret = gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_CRL, &data);
     498             : 
     499           1 :         _gnutls_free_datum(&data);
     500             : 
     501           1 :         return ret;
     502             : }
     503             : 
     504             : /**
     505             :  * gnutls_pkcs12_bag_set_key_id:
     506             :  * @bag: The bag
     507             :  * @indx: The bag's element to add the id
     508             :  * @id: the ID
     509             :  *
     510             :  * This function will add the given key ID, to the specified, by the
     511             :  * index, bag element. The key ID will be encoded as a 'Local key
     512             :  * identifier' bag attribute, which is usually used to distinguish
     513             :  * the local private key and the certificate pair.
     514             :  *
     515             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     516             :  *   negative error value. or a negative error code on error.
     517             :  **/
     518             : int
     519          14 : gnutls_pkcs12_bag_set_key_id(gnutls_pkcs12_bag_t bag, unsigned indx,
     520             :                              const gnutls_datum_t * id)
     521             : {
     522          14 :         int ret;
     523             : 
     524             : 
     525          14 :         if (bag == NULL) {
     526           0 :                 gnutls_assert();
     527           0 :                 return GNUTLS_E_INVALID_REQUEST;
     528             :         }
     529             : 
     530          14 :         if (indx > bag->bag_elements - 1) {
     531           0 :                 gnutls_assert();
     532           0 :                 return GNUTLS_E_INVALID_REQUEST;
     533             :         }
     534             : 
     535          28 :         ret = _gnutls_set_datum(&bag->element[indx].local_key_id,
     536          14 :                                 id->data, id->size);
     537             : 
     538          14 :         if (ret < 0) {
     539           0 :                 gnutls_assert();
     540           0 :                 return ret;
     541             :         }
     542             : 
     543             :         return 0;
     544             : }
     545             : 
     546             : /**
     547             :  * gnutls_pkcs12_bag_get_key_id:
     548             :  * @bag: The bag
     549             :  * @indx: The bag's element to add the id
     550             :  * @id: where the ID will be copied (to be treated as const)
     551             :  *
     552             :  * This function will return the key ID, of the specified bag element.
     553             :  * The key ID is usually used to distinguish the local private key and
     554             :  * the certificate pair.
     555             :  *
     556             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     557             :  *   negative error value. or a negative error code on error.
     558             :  **/
     559             : int
     560          61 : gnutls_pkcs12_bag_get_key_id(gnutls_pkcs12_bag_t bag, unsigned indx,
     561             :                              gnutls_datum_t * id)
     562             : {
     563          61 :         if (bag == NULL) {
     564           0 :                 gnutls_assert();
     565           0 :                 return GNUTLS_E_INVALID_REQUEST;
     566             :         }
     567             : 
     568          61 :         if (indx > bag->bag_elements - 1) {
     569           0 :                 gnutls_assert();
     570           0 :                 return GNUTLS_E_INVALID_REQUEST;
     571             :         }
     572             : 
     573          61 :         id->data = bag->element[indx].local_key_id.data;
     574          61 :         id->size = bag->element[indx].local_key_id.size;
     575             : 
     576          61 :         return 0;
     577             : }
     578             : 
     579             : /**
     580             :  * gnutls_pkcs12_bag_get_friendly_name:
     581             :  * @bag: The bag
     582             :  * @indx: The bag's element to add the id
     583             :  * @name: will hold a pointer to the name (to be treated as const)
     584             :  *
     585             :  * This function will return the friendly name, of the specified bag
     586             :  * element.  The key ID is usually used to distinguish the local
     587             :  * private key and the certificate pair.
     588             :  *
     589             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     590             :  *   negative error value. or a negative error code on error.
     591             :  **/
     592             : int
     593          61 : gnutls_pkcs12_bag_get_friendly_name(gnutls_pkcs12_bag_t bag, unsigned indx,
     594             :                                     char **name)
     595             : {
     596          61 :         if (bag == NULL) {
     597           0 :                 gnutls_assert();
     598           0 :                 return GNUTLS_E_INVALID_REQUEST;
     599             :         }
     600             : 
     601          61 :         if (indx > bag->bag_elements - 1) {
     602           0 :                 gnutls_assert();
     603           0 :                 return GNUTLS_E_INVALID_REQUEST;
     604             :         }
     605             : 
     606          61 :         *name = bag->element[indx].friendly_name;
     607             : 
     608          61 :         return 0;
     609             : }
     610             : 
     611             : 
     612             : /**
     613             :  * gnutls_pkcs12_bag_set_friendly_name:
     614             :  * @bag: The bag
     615             :  * @indx: The bag's element to add the id
     616             :  * @name: the name
     617             :  *
     618             :  * This function will add the given key friendly name, to the
     619             :  * specified, by the index, bag element. The name will be encoded as
     620             :  * a 'Friendly name' bag attribute, which is usually used to set a
     621             :  * user name to the local private key and the certificate pair.
     622             :  *
     623             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
     624             :  *   negative error value. or a negative error code on error.
     625             :  **/
     626             : int
     627          14 : gnutls_pkcs12_bag_set_friendly_name(gnutls_pkcs12_bag_t bag, unsigned indx,
     628             :                                     const char *name)
     629             : {
     630          14 :         if (bag == NULL) {
     631           0 :                 gnutls_assert();
     632           0 :                 return GNUTLS_E_INVALID_REQUEST;
     633             :         }
     634             : 
     635          14 :         if (indx > bag->bag_elements - 1) {
     636           0 :                 gnutls_assert();
     637           0 :                 return GNUTLS_E_INVALID_REQUEST;
     638             :         }
     639             : 
     640          14 :         bag->element[indx].friendly_name = gnutls_strdup(name);
     641             : 
     642          14 :         if (name == NULL) {
     643           0 :                 gnutls_assert();
     644           0 :                 return GNUTLS_E_MEMORY_ERROR;
     645             :         }
     646             : 
     647             :         return 0;
     648             : }
     649             : 
     650             : 
     651             : /**
     652             :  * gnutls_pkcs12_bag_decrypt:
     653             :  * @bag: The bag
     654             :  * @pass: The password used for encryption, must be ASCII.
     655             :  *
     656             :  * This function will decrypt the given encrypted bag and return 0 on
     657             :  * success.
     658             :  *
     659             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
     660             :  *   otherwise a negative error code is returned.
     661             :  **/
     662         420 : int gnutls_pkcs12_bag_decrypt(gnutls_pkcs12_bag_t bag, const char *pass)
     663             : {
     664         420 :         int ret;
     665         420 :         gnutls_datum_t dec;
     666             : 
     667         420 :         if (bag == NULL) {
     668           0 :                 gnutls_assert();
     669           0 :                 return GNUTLS_E_INVALID_REQUEST;
     670             :         }
     671             : 
     672         420 :         if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED) {
     673           0 :                 gnutls_assert();
     674           0 :                 return GNUTLS_E_INVALID_REQUEST;
     675             :         }
     676             : 
     677         420 :         ret =
     678         420 :             _gnutls_pkcs7_decrypt_data(&bag->element[0].data, pass, &dec);
     679             : 
     680         420 :         if (ret < 0) {
     681          22 :                 gnutls_assert();
     682          22 :                 return ret;
     683             :         }
     684             : 
     685             :         /* decryption succeeded. Now decode the SafeContents
     686             :          * stuff, and parse it.
     687             :          */
     688             : 
     689         398 :         _gnutls_free_datum(&bag->element[0].data);
     690             : 
     691         398 :         ret = _pkcs12_decode_safe_contents(&dec, bag);
     692             : 
     693         398 :         _gnutls_free_datum(&dec);
     694             : 
     695         398 :         if (ret < 0) {
     696           5 :                 gnutls_assert();
     697           5 :                 return ret;
     698             :         }
     699             : 
     700             :         return 0;
     701             : }
     702             : 
     703             : /**
     704             :  * gnutls_pkcs12_bag_encrypt:
     705             :  * @bag: The bag
     706             :  * @pass: The password used for encryption, must be ASCII
     707             :  * @flags: should be one of #gnutls_pkcs_encrypt_flags_t elements bitwise or'd
     708             :  *
     709             :  * This function will encrypt the given bag.
     710             :  *
     711             :  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
     712             :  *   otherwise a negative error code is returned.
     713             :  **/
     714             : int
     715          14 : gnutls_pkcs12_bag_encrypt(gnutls_pkcs12_bag_t bag, const char *pass,
     716             :                           unsigned int flags)
     717             : {
     718          14 :         int ret;
     719          14 :         ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
     720          14 :         gnutls_datum_t der = { NULL, 0 };
     721          14 :         gnutls_datum_t enc = { NULL, 0 };
     722          14 :         schema_id id;
     723             : 
     724          14 :         if (bag == NULL) {
     725           0 :                 gnutls_assert();
     726           0 :                 return GNUTLS_E_INVALID_REQUEST;
     727             :         }
     728             : 
     729          14 :         if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED) {
     730           0 :                 gnutls_assert();
     731           0 :                 return GNUTLS_E_INVALID_REQUEST;
     732             :         }
     733             : 
     734             :         /* Encode the whole bag to a safe contents
     735             :          * structure.
     736             :          */
     737          14 :         ret = _pkcs12_encode_safe_contents(bag, &safe_cont, NULL);
     738          14 :         if (ret < 0) {
     739           0 :                 gnutls_assert();
     740           0 :                 return ret;
     741             :         }
     742             : 
     743             :         /* DER encode the SafeContents.
     744             :          */
     745          14 :         ret = _gnutls_x509_der_encode(safe_cont, "", &der, 0);
     746             : 
     747          14 :         asn1_delete_structure(&safe_cont);
     748             : 
     749          14 :         if (ret < 0) {
     750           0 :                 gnutls_assert();
     751           0 :                 return ret;
     752             :         }
     753             : 
     754          14 :         if (flags & GNUTLS_PKCS_PLAIN) {
     755           0 :                 gnutls_assert();
     756           0 :                 return GNUTLS_E_INVALID_REQUEST;
     757             :         }
     758             : 
     759          14 :         id = _gnutls_pkcs_flags_to_schema(flags);
     760             : 
     761             :         /* Now encrypt them.
     762             :          */
     763          14 :         ret = _gnutls_pkcs7_encrypt_data(id, &der, pass, &enc);
     764             : 
     765          14 :         _gnutls_free_datum(&der);
     766             : 
     767          14 :         if (ret < 0) {
     768           0 :                 gnutls_assert();
     769           0 :                 return ret;
     770             :         }
     771             : 
     772             :         /* encryption succeeded. 
     773             :          */
     774             : 
     775          14 :         _pkcs12_bag_free_data(bag);
     776             : 
     777          14 :         bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
     778          14 :         bag->element[0].data = enc;
     779             : 
     780          14 :         bag->bag_elements = 1;
     781             : 
     782             : 
     783          14 :         return 0;
     784             : }
     785             : 
     786             : /**
     787             :  * gnutls_pkcs12_bag_enc_info:
     788             :  * @bag: The bag
     789             :  * @schema: indicate the schema as one of %gnutls_pkcs_encrypt_flags_t
     790             :  * @cipher: the cipher used as %gnutls_cipher_algorithm_t
     791             :  * @salt: PBKDF2 salt (if non-NULL then @salt_size initially holds its size)
     792             :  * @salt_size: PBKDF2 salt size
     793             :  * @iter_count: PBKDF2 iteration count
     794             :  * @oid: if non-NULL it will contain an allocated null-terminated variable with the OID
     795             :  *
     796             :  * This function will provide information on the encryption algorithms used
     797             :  * in an encrypted bag. If the structure algorithms
     798             :  * are unknown the code %GNUTLS_E_UNKNOWN_CIPHER_TYPE will be returned,
     799             :  * and only @oid, will be set. That is, @oid will be set on encrypted bags
     800             :  * whether supported or not. It must be deinitialized using gnutls_free().
     801             :  * The other variables are only set on supported structures.
     802             :  *
     803             :  * Returns: %GNUTLS_E_INVALID_REQUEST if the provided bag isn't encrypted,
     804             :  *  %GNUTLS_E_UNKNOWN_CIPHER_TYPE if the structure's encryption isn't supported, or
     805             :  *  another negative error code in case of a failure. Zero on success.
     806             :  **/
     807             : int
     808          32 : gnutls_pkcs12_bag_enc_info(gnutls_pkcs12_bag_t bag, unsigned int *schema, unsigned int *cipher,
     809             :         void *salt, unsigned int *salt_size, unsigned int *iter_count, char **oid)
     810             : {
     811          32 :         int ret;
     812          32 :         struct pbkdf2_params kdf;
     813          32 :         const struct pkcs_cipher_schema_st *p;
     814             : 
     815          32 :         if (bag == NULL) {
     816           0 :                 gnutls_assert();
     817           0 :                 return GNUTLS_E_INVALID_REQUEST;
     818             :         }
     819             : 
     820          32 :         if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED) {
     821           0 :                 gnutls_assert();
     822           0 :                 return GNUTLS_E_INVALID_REQUEST;
     823             :         }
     824             : 
     825          32 :         ret =
     826          32 :             _gnutls_pkcs7_data_enc_info(&bag->element[0].data, &p, &kdf, oid);
     827             : 
     828          32 :         if (ret < 0) {
     829           4 :                 gnutls_assert();
     830           4 :                 return ret;
     831             :         }
     832             : 
     833          28 :         if (schema)
     834          28 :                 *schema = p->flag;
     835             : 
     836          28 :         if (cipher)
     837          28 :                 *cipher = p->cipher;
     838             : 
     839          28 :         if (iter_count)
     840          28 :                  *iter_count = kdf.iter_count;
     841             : 
     842          28 :         if (salt) {
     843          28 :                 if (*salt_size >= (unsigned)kdf.salt_size) {
     844          28 :                         memcpy(salt, kdf.salt, kdf.salt_size);
     845             :                 } else {
     846           0 :                         *salt_size = kdf.salt_size;
     847           0 :                         return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
     848             :                 }
     849             :         }
     850             : 
     851          28 :         if (salt_size)
     852          28 :                 *salt_size = kdf.salt_size;
     853             : 
     854             : 
     855             :         return 0;
     856             : }
     857             : 
     858             : /**
     859             :  * gnutls_pkcs12_bag_set_privkey:
     860             :  * @bag: The bag
     861             :  * @privkey: the private key to be copied.
     862             :  * @password: the password to protect the key with (may be %NULL)
     863             :  * @flags: should be one of #gnutls_pkcs_encrypt_flags_t elements bitwise or'd
     864             :  *
     865             :  * This function will insert the given private key into the
     866             :  * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
     867             :  *
     868             :  * Returns: the index of the added bag on success, or a negative
     869             :  * value on failure.
     870             :  **/
     871             : int
     872           0 : gnutls_pkcs12_bag_set_privkey(gnutls_pkcs12_bag_t bag, gnutls_x509_privkey_t privkey,
     873             :                               const char *password, unsigned flags)
     874             : {
     875           0 :         int ret;
     876           0 :         gnutls_datum_t data = {NULL, 0};
     877             : 
     878           0 :         if (bag == NULL) {
     879           0 :                 gnutls_assert();
     880           0 :                 return GNUTLS_E_INVALID_REQUEST;
     881             :         }
     882             : 
     883           0 :         ret = gnutls_x509_privkey_export2_pkcs8(privkey, GNUTLS_X509_FMT_DER,
     884             :                                                 password, flags, &data);
     885           0 :         if (ret < 0)
     886           0 :                 return gnutls_assert_val(ret);
     887             : 
     888           0 :         if (password == NULL) {
     889           0 :                 ret = gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_PKCS8_KEY, &data);
     890           0 :                 if (ret < 0) {
     891           0 :                         gnutls_assert();
     892           0 :                         goto cleanup;
     893             :                 }
     894             :         } else {
     895           0 :                 ret = gnutls_pkcs12_bag_set_data(bag, GNUTLS_BAG_PKCS8_ENCRYPTED_KEY, &data);
     896           0 :                 if (ret < 0) {
     897           0 :                         gnutls_assert();
     898           0 :                         goto cleanup;
     899             :                 }
     900             :         }
     901             : 
     902           0 :  cleanup:
     903           0 :         _gnutls_free_datum(&data);
     904             : 
     905           0 :         return ret;
     906             : }

Generated by: LCOV version 1.14