LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/hx509 - ks_p12.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 3 359 0.8 %
Date: 2024-04-21 15:09:00 Functions: 1 20 5.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "hx_locl.h"
      35             : 
      36             : struct ks_pkcs12 {
      37             :     hx509_certs certs;
      38             :     char *fn;
      39             :     unsigned int store_no_priv_keys;
      40             : };
      41             : 
      42             : typedef int (*collector_func)(hx509_context,
      43             :                               struct hx509_collector *,
      44             :                               int,
      45             :                               const void *, size_t,
      46             :                               const PKCS12_Attributes *);
      47             : 
      48             : struct type {
      49             :     const heim_oid *oid;
      50             :     collector_func func;
      51             : };
      52             : 
      53             : static void
      54             : parse_pkcs12_type(hx509_context, struct hx509_collector *, int,
      55             :                   const heim_oid *, const void *, size_t,
      56             :                   const PKCS12_Attributes *);
      57             : 
      58             : 
      59             : static const PKCS12_Attribute *
      60           0 : find_attribute(const PKCS12_Attributes *attrs, const heim_oid *oid)
      61             : {
      62           0 :     size_t i;
      63           0 :     if (attrs == NULL)
      64           0 :         return NULL;
      65           0 :     for (i = 0; i < attrs->len; i++)
      66           0 :         if (der_heim_oid_cmp(oid, &attrs->val[i].attrId) == 0)
      67           0 :             return &attrs->val[i];
      68           0 :     return NULL;
      69             : }
      70             : 
      71             : static int
      72           0 : keyBag_parser(hx509_context context,
      73             :               struct hx509_collector *c,
      74             :               int flags,
      75             :               const void *data, size_t length,
      76             :               const PKCS12_Attributes *attrs)
      77             : {
      78           0 :     const PKCS12_Attribute *attr;
      79           0 :     PKCS8PrivateKeyInfo ki;
      80           0 :     const heim_octet_string *os = NULL;
      81           0 :     int ret;
      82             : 
      83           0 :     if (flags & HX509_CERTS_NO_PRIVATE_KEYS)
      84           0 :         return 0;
      85             : 
      86           0 :     attr = find_attribute(attrs, &asn1_oid_id_pkcs_9_at_localKeyId);
      87           0 :     if (attr)
      88           0 :         os = &attr->attrValues;
      89             : 
      90           0 :     ret = decode_PKCS8PrivateKeyInfo(data, length, &ki, NULL);
      91           0 :     if (ret)
      92           0 :         return ret;
      93             : 
      94           0 :     ret = _hx509_collector_private_key_add(context,
      95             :                                            c,
      96             :                                            &ki.privateKeyAlgorithm,
      97             :                                            NULL,
      98             :                                            &ki.privateKey,
      99             :                                            os);
     100           0 :     free_PKCS8PrivateKeyInfo(&ki);
     101           0 :     return ret;
     102             : }
     103             : 
     104             : static int
     105           0 : ShroudedKeyBag_parser(hx509_context context,
     106             :                       struct hx509_collector *c,
     107             :                       int flags,
     108             :                       const void *data, size_t length,
     109             :                       const PKCS12_Attributes *attrs)
     110             : {
     111           0 :     PKCS8EncryptedPrivateKeyInfo pk;
     112           0 :     heim_octet_string content;
     113           0 :     int ret;
     114             : 
     115           0 :     memset(&pk, 0, sizeof(pk));
     116             : 
     117           0 :     ret = decode_PKCS8EncryptedPrivateKeyInfo(data, length, &pk, NULL);
     118           0 :     if (ret)
     119           0 :         return ret;
     120             : 
     121           0 :     ret = _hx509_pbe_decrypt(context,
     122             :                              _hx509_collector_get_lock(c),
     123             :                              &pk.encryptionAlgorithm,
     124             :                              &pk.encryptedData,
     125             :                              &content);
     126           0 :     free_PKCS8EncryptedPrivateKeyInfo(&pk);
     127           0 :     if (ret)
     128           0 :         return ret;
     129             : 
     130           0 :     ret = keyBag_parser(context, c, flags, content.data, content.length,
     131             :                         attrs);
     132           0 :     der_free_octet_string(&content);
     133           0 :     return ret;
     134             : }
     135             : 
     136             : static int
     137           0 : certBag_parser(hx509_context context,
     138             :                struct hx509_collector *c,
     139             :                int flags,
     140             :                const void *data, size_t length,
     141             :                const PKCS12_Attributes *attrs)
     142             : {
     143           0 :     heim_error_t error = NULL;
     144           0 :     heim_octet_string os;
     145           0 :     hx509_cert cert;
     146           0 :     PKCS12_CertBag cb;
     147           0 :     int ret;
     148             : 
     149           0 :     ret = decode_PKCS12_CertBag(data, length, &cb, NULL);
     150           0 :     if (ret)
     151           0 :         return ret;
     152             : 
     153           0 :     if (der_heim_oid_cmp(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType)) {
     154           0 :         free_PKCS12_CertBag(&cb);
     155           0 :         return 0;
     156             :     }
     157             : 
     158           0 :     ret = decode_PKCS12_OctetString(cb.certValue.data,
     159             :                                     cb.certValue.length,
     160             :                                     &os,
     161             :                                     NULL);
     162           0 :     free_PKCS12_CertBag(&cb);
     163           0 :     if (ret)
     164           0 :         return ret;
     165             : 
     166           0 :     cert = hx509_cert_init_data(context, os.data, os.length, &error);
     167           0 :     der_free_octet_string(&os);
     168           0 :     if (cert == NULL) {
     169           0 :         ret = heim_error_get_code(error);
     170           0 :         heim_release(error);
     171           0 :         return ret;
     172             :     }
     173             : 
     174           0 :     ret = _hx509_collector_certs_add(context, c, cert);
     175           0 :     if (ret) {
     176           0 :         hx509_cert_free(cert);
     177           0 :         return ret;
     178             :     }
     179             : 
     180             :     {
     181           0 :         const PKCS12_Attribute *attr;
     182           0 :         const heim_oid *oids[] = {
     183             :             &asn1_oid_id_pkcs_9_at_localKeyId, &asn1_oid_id_pkcs_9_at_friendlyName
     184             :         };
     185           0 :         size_t i;
     186             : 
     187           0 :         for  (i = 0; i < sizeof(oids)/sizeof(oids[0]); i++) {
     188           0 :             const heim_oid *oid = oids[i];
     189           0 :             attr = find_attribute(attrs, oid);
     190           0 :             if (attr)
     191           0 :                 _hx509_set_cert_attribute(context, cert, oid,
     192           0 :                                           &attr->attrValues);
     193             :         }
     194             :     }
     195             : 
     196           0 :     hx509_cert_free(cert);
     197             : 
     198           0 :     return 0;
     199             : }
     200             : 
     201             : static int
     202           0 : parse_safe_content(hx509_context context,
     203             :                    struct hx509_collector *c,
     204             :                    int flags,
     205             :                    const unsigned char *p, size_t len)
     206             : {
     207           0 :     PKCS12_SafeContents sc;
     208           0 :     int ret;
     209           0 :     size_t i;
     210             : 
     211           0 :     memset(&sc, 0, sizeof(sc));
     212             : 
     213           0 :     ret = decode_PKCS12_SafeContents(p, len, &sc, NULL);
     214           0 :     if (ret)
     215           0 :         return ret;
     216             : 
     217           0 :     for (i = 0; i < sc.len ; i++)
     218           0 :         parse_pkcs12_type(context,
     219             :                           c,
     220             :                           flags,
     221           0 :                           &sc.val[i].bagId,
     222           0 :                           sc.val[i].bagValue.data,
     223           0 :                           sc.val[i].bagValue.length,
     224           0 :                           sc.val[i].bagAttributes);
     225             : 
     226           0 :     free_PKCS12_SafeContents(&sc);
     227           0 :     return 0;
     228             : }
     229             : 
     230             : static int
     231           0 : safeContent_parser(hx509_context context,
     232             :                    struct hx509_collector *c,
     233             :                    int flags,
     234             :                    const void *data, size_t length,
     235             :                    const PKCS12_Attributes *attrs)
     236             : {
     237           0 :     heim_octet_string os;
     238           0 :     int ret;
     239             : 
     240           0 :     ret = decode_PKCS12_OctetString(data, length, &os, NULL);
     241           0 :     if (ret)
     242           0 :         return ret;
     243           0 :     ret = parse_safe_content(context, c, flags, os.data, os.length);
     244           0 :     der_free_octet_string(&os);
     245           0 :     return ret;
     246             : }
     247             : 
     248             : static int
     249           0 : encryptedData_parser(hx509_context context,
     250             :                      struct hx509_collector *c,
     251             :                      int flags,
     252             :                      const void *data, size_t length,
     253             :                      const PKCS12_Attributes *attrs)
     254             : {
     255           0 :     heim_octet_string content;
     256           0 :     heim_oid contentType;
     257           0 :     int ret;
     258             : 
     259           0 :     memset(&contentType, 0, sizeof(contentType));
     260             : 
     261           0 :     ret = hx509_cms_decrypt_encrypted(context,
     262             :                                       _hx509_collector_get_lock(c),
     263             :                                       data, length,
     264             :                                       &contentType,
     265             :                                       &content);
     266           0 :     if (ret)
     267           0 :         return ret;
     268             : 
     269           0 :     if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
     270           0 :         ret = parse_safe_content(context, c, flags,
     271           0 :                                  content.data, content.length);
     272             : 
     273           0 :     der_free_octet_string(&content);
     274           0 :     der_free_oid(&contentType);
     275           0 :     return ret;
     276             : }
     277             : 
     278             : static int
     279           0 : envelopedData_parser(hx509_context context,
     280             :                      struct hx509_collector *c,
     281             :                      int flags,
     282             :                      const void *data, size_t length,
     283             :                      const PKCS12_Attributes *attrs)
     284             : {
     285           0 :     heim_octet_string content;
     286           0 :     heim_oid contentType;
     287           0 :     hx509_lock lock;
     288           0 :     int ret;
     289             : 
     290           0 :     memset(&contentType, 0, sizeof(contentType));
     291             : 
     292           0 :     lock = _hx509_collector_get_lock(c);
     293             : 
     294           0 :     ret = hx509_cms_unenvelope(context,
     295             :                                _hx509_lock_unlock_certs(lock),
     296             :                                0,
     297             :                                data, length,
     298             :                                NULL,
     299             :                                0,
     300             :                                &contentType,
     301             :                                &content);
     302           0 :     if (ret) {
     303           0 :         hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
     304             :                                "PKCS12 failed to unenvelope");
     305           0 :         return ret;
     306             :     }
     307             : 
     308           0 :     if (der_heim_oid_cmp(&contentType, &asn1_oid_id_pkcs7_data) == 0)
     309           0 :         ret = parse_safe_content(context, c, flags,
     310           0 :                                  content.data, content.length);
     311             : 
     312           0 :     der_free_octet_string(&content);
     313           0 :     der_free_oid(&contentType);
     314             : 
     315           0 :     return ret;
     316             : }
     317             : 
     318             : 
     319             : struct type bagtypes[] = {
     320             :     { &asn1_oid_id_pkcs12_keyBag, keyBag_parser },
     321             :     { &asn1_oid_id_pkcs12_pkcs8ShroudedKeyBag, ShroudedKeyBag_parser },
     322             :     { &asn1_oid_id_pkcs12_certBag, certBag_parser },
     323             :     { &asn1_oid_id_pkcs7_data, safeContent_parser },
     324             :     { &asn1_oid_id_pkcs7_encryptedData, encryptedData_parser },
     325             :     { &asn1_oid_id_pkcs7_envelopedData, envelopedData_parser }
     326             : };
     327             : 
     328             : static void
     329           0 : parse_pkcs12_type(hx509_context context,
     330             :                   struct hx509_collector *c,
     331             :                   int flags,
     332             :                   const heim_oid *oid,
     333             :                   const void *data, size_t length,
     334             :                   const PKCS12_Attributes *attrs)
     335             : {
     336           0 :     size_t i;
     337             : 
     338           0 :     for (i = 0; i < sizeof(bagtypes)/sizeof(bagtypes[0]); i++)
     339           0 :         if (der_heim_oid_cmp(bagtypes[i].oid, oid) == 0)
     340           0 :             (*bagtypes[i].func)(context, c, flags, data, length, attrs);
     341           0 : }
     342             : 
     343             : static int
     344           0 : p12_init(hx509_context context,
     345             :          hx509_certs certs, void **data, int flags,
     346             :          const char *residue, hx509_lock lock)
     347             : {
     348           0 :     struct ks_pkcs12 *p12;
     349           0 :     size_t len;
     350           0 :     void *buf;
     351           0 :     PKCS12_PFX pfx;
     352           0 :     PKCS12_AuthenticatedSafe as;
     353           0 :     int ret;
     354           0 :     size_t i;
     355           0 :     struct hx509_collector *c;
     356             : 
     357           0 :     *data = NULL;
     358             : 
     359           0 :     if (residue == NULL || residue[0] == '\0') {
     360           0 :         hx509_set_error_string(context, 0, EINVAL,
     361             :                                "PKCS#12 file not specified");
     362           0 :         return EINVAL;
     363             :     }
     364             : 
     365           0 :     if (lock == NULL)
     366           0 :         lock = _hx509_empty_lock;
     367             : 
     368           0 :     ret = _hx509_collector_alloc(context, lock, &c);
     369           0 :     if (ret)
     370           0 :         return ret;
     371             : 
     372           0 :     p12 = calloc(1, sizeof(*p12));
     373           0 :     if (p12 == NULL) {
     374           0 :         ret = ENOMEM;
     375           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     376           0 :         goto out;
     377             :     }
     378             : 
     379           0 :     p12->fn = strdup(residue);
     380           0 :     if (p12->fn == NULL) {
     381           0 :         ret = ENOMEM;
     382           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     383           0 :         goto out;
     384             :     }
     385             : 
     386           0 :     if (flags & HX509_CERTS_CREATE) {
     387           0 :         ret = hx509_certs_init(context, "MEMORY:ks-file-create",
     388             :                                0, lock, &p12->certs);
     389           0 :         if (ret == 0)
     390           0 :             *data = p12;
     391           0 :         goto out;
     392             :     }
     393             : 
     394           0 :     ret = rk_undumpdata(residue, &buf, &len);
     395           0 :     if (ret) {
     396           0 :         hx509_clear_error_string(context);
     397           0 :         goto out;
     398             :     }
     399             : 
     400           0 :     ret = decode_PKCS12_PFX(buf, len, &pfx, NULL);
     401           0 :     rk_xfree(buf);
     402           0 :     if (ret) {
     403           0 :         hx509_set_error_string(context, 0, ret,
     404             :                                "Failed to decode the PFX in %s", residue);
     405           0 :         goto out;
     406             :     }
     407             : 
     408           0 :     if (der_heim_oid_cmp(&pfx.authSafe.contentType, &asn1_oid_id_pkcs7_data) != 0) {
     409           0 :         free_PKCS12_PFX(&pfx);
     410           0 :         ret = EINVAL;
     411           0 :         hx509_set_error_string(context, 0, ret,
     412             :                                "PKCS PFX isn't a pkcs7-data container");
     413           0 :         goto out;
     414             :     }
     415             : 
     416           0 :     if (pfx.authSafe.content == NULL) {
     417           0 :         free_PKCS12_PFX(&pfx);
     418           0 :         ret = EINVAL;
     419           0 :         hx509_set_error_string(context, 0, ret,
     420             :                                "PKCS PFX missing data");
     421           0 :         goto out;
     422             :     }
     423             : 
     424             :     {
     425           0 :         heim_octet_string asdata;
     426             : 
     427           0 :         ret = decode_PKCS12_OctetString(pfx.authSafe.content->data,
     428           0 :                                         pfx.authSafe.content->length,
     429             :                                         &asdata,
     430             :                                         NULL);
     431           0 :         free_PKCS12_PFX(&pfx);
     432           0 :         if (ret) {
     433           0 :             hx509_clear_error_string(context);
     434           0 :             goto out;
     435             :         }
     436           0 :         ret = decode_PKCS12_AuthenticatedSafe(asdata.data,
     437             :                                               asdata.length,
     438             :                                               &as,
     439             :                                               NULL);
     440           0 :         der_free_octet_string(&asdata);
     441           0 :         if (ret) {
     442           0 :             hx509_clear_error_string(context);
     443           0 :             goto out;
     444             :         }
     445             :     }
     446             : 
     447           0 :     for (i = 0; i < as.len; i++)
     448           0 :         parse_pkcs12_type(context,
     449             :                           c,
     450             :                           flags,
     451           0 :                           &as.val[i].contentType,
     452           0 :                           as.val[i].content->data,
     453           0 :                           as.val[i].content->length,
     454             :                           NULL);
     455             : 
     456           0 :     free_PKCS12_AuthenticatedSafe(&as);
     457             : 
     458           0 :     ret = _hx509_collector_collect_certs(context, c, &p12->certs);
     459           0 :     if (ret == 0)
     460           0 :         *data = p12;
     461             : 
     462           0 : out:
     463           0 :     _hx509_collector_free(c);
     464             : 
     465           0 :     if (ret && p12) {
     466           0 :         if (p12->fn)
     467           0 :             free(p12->fn);
     468           0 :         if (p12->certs)
     469           0 :             hx509_certs_free(&p12->certs);
     470           0 :         free(p12);
     471             :     }
     472             : 
     473           0 :     return ret;
     474             : }
     475             : 
     476             : static int
     477           0 : addBag(hx509_context context,
     478             :        PKCS12_AuthenticatedSafe *as,
     479             :        const heim_oid *oid,
     480             :        void *data,
     481             :        size_t length)
     482             : {
     483           0 :     void *ptr;
     484           0 :     int ret;
     485             : 
     486           0 :     ptr = realloc(as->val, sizeof(as->val[0]) * (as->len + 1));
     487           0 :     if (ptr == NULL) {
     488           0 :         hx509_set_error_string(context, 0, ENOMEM, "out of memory");
     489           0 :         return ENOMEM;
     490             :     }
     491           0 :     as->val = ptr;
     492             : 
     493           0 :     ret = der_copy_oid(oid, &as->val[as->len].contentType);
     494           0 :     if (ret) {
     495           0 :         hx509_set_error_string(context, 0, ret, "out of memory");
     496           0 :         return ret;
     497             :     }
     498             : 
     499           0 :     as->val[as->len].content = calloc(1, sizeof(*as->val[0].content));
     500           0 :     if (as->val[as->len].content == NULL) {
     501           0 :         der_free_oid(&as->val[as->len].contentType);
     502           0 :         hx509_set_error_string(context, 0, ENOMEM, "malloc out of memory");
     503           0 :         return ENOMEM;
     504             :     }
     505             : 
     506           0 :     as->val[as->len].content->data = data;
     507           0 :     as->val[as->len].content->length = length;
     508             : 
     509           0 :     as->len++;
     510             : 
     511           0 :     return 0;
     512             : }
     513             : 
     514             : struct store_func_ctx {
     515             :     PKCS12_AuthenticatedSafe as;
     516             :     int store_flags;
     517             : };
     518             : 
     519             : static int HX509_LIB_CALL
     520           0 : store_func(hx509_context context, void *d, hx509_cert c)
     521             : {
     522           0 :     struct store_func_ctx *ctx = d;
     523           0 :     PKCS12_OctetString os;
     524           0 :     PKCS12_CertBag cb;
     525           0 :     size_t size;
     526           0 :     int ret;
     527             : 
     528           0 :     if ((ctx->store_flags & HX509_CERTS_STORE_NO_ROOTS)) {
     529           0 :         int is_root = 0;
     530             : 
     531           0 :         ret = hx509_cert_is_root(context, c, &is_root);
     532           0 :         if (ret || is_root)
     533           0 :             return ret;
     534             :     }
     535             : 
     536           0 :     memset(&os, 0, sizeof(os));
     537           0 :     memset(&cb, 0, sizeof(cb));
     538             : 
     539           0 :     os.data = NULL;
     540           0 :     os.length = 0;
     541             : 
     542           0 :     ret = hx509_cert_binary(context, c, &os);
     543           0 :     if (ret)
     544           0 :         return ret;
     545             : 
     546           0 :     ASN1_MALLOC_ENCODE(PKCS12_OctetString,
     547             :                        cb.certValue.data,cb.certValue.length,
     548             :                        &os, &size, ret);
     549           0 :     free(os.data);
     550           0 :     if (ret)
     551           0 :         goto out;
     552           0 :     ret = der_copy_oid(&asn1_oid_id_pkcs_9_at_certTypes_x509, &cb.certType);
     553           0 :     if (ret) {
     554           0 :         free_PKCS12_CertBag(&cb);
     555           0 :         goto out;
     556             :     }
     557           0 :     ASN1_MALLOC_ENCODE(PKCS12_CertBag, os.data, os.length,
     558             :                        &cb, &size, ret);
     559           0 :     free_PKCS12_CertBag(&cb);
     560           0 :     if (ret)
     561           0 :         goto out;
     562             : 
     563           0 :     ret = addBag(context, &ctx->as, &asn1_oid_id_pkcs12_certBag, os.data,
     564             :                  os.length);
     565             : 
     566           0 :     if (_hx509_cert_private_key_exportable(c) &&
     567           0 :         !(ctx->store_flags & HX509_CERTS_STORE_NO_PRIVATE_KEYS)) {
     568           0 :         hx509_private_key key = _hx509_cert_private_key(c);
     569           0 :         PKCS8PrivateKeyInfo pki;
     570             : 
     571           0 :         memset(&pki, 0, sizeof(pki));
     572             : 
     573           0 :         ret = der_parse_hex_heim_integer("00", &pki.version);
     574           0 :         if (ret)
     575           0 :             return ret;
     576           0 :         ret = _hx509_private_key_oid(context, key,
     577             :                                      &pki.privateKeyAlgorithm.algorithm);
     578           0 :         if (ret) {
     579           0 :             free_PKCS8PrivateKeyInfo(&pki);
     580           0 :             return ret;
     581             :         }
     582           0 :         ret = _hx509_private_key_export(context,
     583             :                                         _hx509_cert_private_key(c),
     584             :                                         HX509_KEY_FORMAT_DER,
     585             :                                         &pki.privateKey);
     586           0 :         if (ret) {
     587           0 :             free_PKCS8PrivateKeyInfo(&pki);
     588           0 :             return ret;
     589             :         }
     590             :         /* set attribute, asn1_oid_id_pkcs_9_at_localKeyId */
     591             : 
     592           0 :         ASN1_MALLOC_ENCODE(PKCS8PrivateKeyInfo, os.data, os.length,
     593             :                            &pki, &size, ret);
     594           0 :         free_PKCS8PrivateKeyInfo(&pki);
     595           0 :         if (ret)
     596           0 :             return ret;
     597             : 
     598           0 :         ret = addBag(context, &ctx->as, &asn1_oid_id_pkcs12_keyBag, os.data,
     599             :                      os.length);
     600           0 :         if (ret)
     601           0 :             return ret;
     602             :     }
     603             : 
     604           0 : out:
     605           0 :     return ret;
     606             : }
     607             : 
     608             : static int
     609           0 : p12_store(hx509_context context,
     610             :           hx509_certs certs, void *data, int flags, hx509_lock lock)
     611             : {
     612           0 :     struct ks_pkcs12 *p12 = data;
     613           0 :     PKCS12_PFX pfx;
     614           0 :     struct store_func_ctx ctx;
     615           0 :     PKCS12_OctetString asdata;
     616           0 :     size_t size;
     617           0 :     int ret;
     618             : 
     619           0 :     memset(&ctx, 0, sizeof(ctx));
     620           0 :     memset(&pfx, 0, sizeof(pfx));
     621           0 :     ctx.store_flags = flags;
     622             : 
     623           0 :     ret = hx509_certs_iter_f(context, p12->certs, store_func, &ctx);
     624           0 :     if (ret)
     625           0 :         goto out;
     626             : 
     627           0 :     ASN1_MALLOC_ENCODE(PKCS12_AuthenticatedSafe, asdata.data, asdata.length,
     628             :                        &ctx.as, &size, ret);
     629           0 :     free_PKCS12_AuthenticatedSafe(&ctx.as);
     630           0 :     if (ret)
     631           0 :         return ret;
     632             : 
     633           0 :     ret = der_parse_hex_heim_integer("03", &pfx.version);
     634           0 :     if (ret) {
     635           0 :         free(asdata.data);
     636           0 :         goto out;
     637             :     }
     638             : 
     639           0 :     pfx.authSafe.content = calloc(1, sizeof(*pfx.authSafe.content));
     640             : 
     641           0 :     ASN1_MALLOC_ENCODE(PKCS12_OctetString,
     642             :                        pfx.authSafe.content->data,
     643             :                        pfx.authSafe.content->length,
     644             :                        &asdata, &size, ret);
     645           0 :     free(asdata.data);
     646           0 :     if (ret)
     647           0 :         goto out;
     648             : 
     649           0 :     ret = der_copy_oid(&asn1_oid_id_pkcs7_data, &pfx.authSafe.contentType);
     650           0 :     if (ret)
     651           0 :         goto out;
     652             : 
     653           0 :     ASN1_MALLOC_ENCODE(PKCS12_PFX, asdata.data, asdata.length,
     654             :                        &pfx, &size, ret);
     655           0 :     if (ret)
     656           0 :         goto out;
     657             : 
     658             : #if 0
     659             :     const struct _hx509_password *pw;
     660             : 
     661             :     pw = _hx509_lock_get_passwords(lock);
     662             :     if (pw != NULL) {
     663             :         pfx.macData = calloc(1, sizeof(*pfx.macData));
     664             :         if (pfx.macData == NULL) {
     665             :             ret = ENOMEM;
     666             :             hx509_set_error_string(context, 0, ret, "malloc out of memory");
     667             :             return ret;
     668             :         }
     669             :         if (pfx.macData == NULL) {
     670             :             free(asdata.data);
     671             :             goto out;
     672             :         }
     673             :     }
     674             :     ret = calculate_hash(&aspath, pw, pfx.macData);
     675             : #endif
     676             : 
     677           0 :     rk_dumpdata(p12->fn, asdata.data, asdata.length);
     678           0 :     free(asdata.data);
     679             : 
     680           0 : out:
     681           0 :     free_PKCS12_AuthenticatedSafe(&ctx.as);
     682           0 :     free_PKCS12_PFX(&pfx);
     683             : 
     684           0 :     return ret;
     685             : }
     686             : 
     687             : 
     688             : static int
     689           0 : p12_free(hx509_certs certs, void *data)
     690             : {
     691           0 :     struct ks_pkcs12 *p12 = data;
     692           0 :     hx509_certs_free(&p12->certs);
     693           0 :     free(p12->fn);
     694           0 :     free(p12);
     695           0 :     return 0;
     696             : }
     697             : 
     698             : static int
     699           0 : p12_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c)
     700             : {
     701           0 :     struct ks_pkcs12 *p12 = data;
     702           0 :     return hx509_certs_add(context, p12->certs, c);
     703             : }
     704             : 
     705             : static int
     706           0 : p12_iter_start(hx509_context context,
     707             :                hx509_certs certs,
     708             :                void *data,
     709             :                void **cursor)
     710             : {
     711           0 :     struct ks_pkcs12 *p12 = data;
     712           0 :     return hx509_certs_start_seq(context, p12->certs, cursor);
     713             : }
     714             : 
     715             : static int
     716           0 : p12_iter(hx509_context context,
     717             :          hx509_certs certs,
     718             :          void *data,
     719             :          void *cursor,
     720             :          hx509_cert *cert)
     721             : {
     722           0 :     struct ks_pkcs12 *p12 = data;
     723           0 :     return hx509_certs_next_cert(context, p12->certs, cursor, cert);
     724             : }
     725             : 
     726             : static int
     727           0 : p12_iter_end(hx509_context context,
     728             :              hx509_certs certs,
     729             :              void *data,
     730             :              void *cursor)
     731             : {
     732           0 :     struct ks_pkcs12 *p12 = data;
     733           0 :     return hx509_certs_end_seq(context, p12->certs, cursor);
     734             : }
     735             : 
     736             : static int
     737           0 : p12_destroy(hx509_context context, hx509_certs certs, void *data)
     738             : {
     739           0 :     struct ks_pkcs12 *p12 = data;
     740           0 :     return _hx509_erase_file(context, p12->fn);
     741             : }
     742             : 
     743             : static struct hx509_keyset_ops keyset_pkcs12 = {
     744             :     "PKCS12",
     745             :     0,
     746             :     p12_init,
     747             :     p12_store,
     748             :     p12_free,
     749             :     p12_add,
     750             :     NULL,
     751             :     p12_iter_start,
     752             :     p12_iter,
     753             :     p12_iter_end,
     754             :     NULL,
     755             :     NULL,
     756             :     NULL,
     757             :     p12_destroy
     758             : };
     759             : 
     760             : HX509_LIB_FUNCTION void HX509_LIB_CALL
     761      792004 : _hx509_ks_pkcs12_register(hx509_context context)
     762             : {
     763      792004 :     _hx509_ks_register(context, &keyset_pkcs12);
     764      792004 : }

Generated by: LCOV version 1.14