LCOV - code coverage report
Current view: top level - contrib/pgcrypto - pgp-pubkey.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 350 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 9 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * pgp-pubkey.c
       3              :  *        Read public or secret key.
       4              :  *
       5              :  * Copyright (c) 2005 Marko Kreen
       6              :  * All rights reserved.
       7              :  *
       8              :  * Redistribution and use in source and binary forms, with or without
       9              :  * modification, are permitted provided that the following conditions
      10              :  * are met:
      11              :  * 1. Redistributions of source code must retain the above copyright
      12              :  *        notice, this list of conditions and the following disclaimer.
      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              :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
      18              :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      19              :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      20              :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      21              :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      22              :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      23              :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      24              :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      25              :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      26              :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      27              :  * SUCH DAMAGE.
      28              :  *
      29              :  * contrib/pgcrypto/pgp-pubkey.c
      30              :  */
      31              : #include "postgres.h"
      32              : 
      33              : #include "mbuf.h"
      34              : #include "pgp.h"
      35              : #include "px.h"
      36              : 
      37              : int
      38            0 : pgp_key_alloc(PGP_PubKey **pk_p)
      39              : {
      40            0 :         PGP_PubKey *pk;
      41              : 
      42            0 :         pk = palloc0_object(PGP_PubKey);
      43            0 :         *pk_p = pk;
      44            0 :         return 0;
      45            0 : }
      46              : 
      47              : void
      48            0 : pgp_key_free(PGP_PubKey *pk)
      49              : {
      50            0 :         if (pk == NULL)
      51            0 :                 return;
      52              : 
      53            0 :         switch (pk->algo)
      54              :         {
      55              :                 case PGP_PUB_ELG_ENCRYPT:
      56            0 :                         pgp_mpi_free(pk->pub.elg.p);
      57            0 :                         pgp_mpi_free(pk->pub.elg.g);
      58            0 :                         pgp_mpi_free(pk->pub.elg.y);
      59            0 :                         pgp_mpi_free(pk->sec.elg.x);
      60            0 :                         break;
      61              :                 case PGP_PUB_RSA_SIGN:
      62              :                 case PGP_PUB_RSA_ENCRYPT:
      63              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
      64            0 :                         pgp_mpi_free(pk->pub.rsa.n);
      65            0 :                         pgp_mpi_free(pk->pub.rsa.e);
      66            0 :                         pgp_mpi_free(pk->sec.rsa.d);
      67            0 :                         pgp_mpi_free(pk->sec.rsa.p);
      68            0 :                         pgp_mpi_free(pk->sec.rsa.q);
      69            0 :                         pgp_mpi_free(pk->sec.rsa.u);
      70            0 :                         break;
      71              :                 case PGP_PUB_DSA_SIGN:
      72            0 :                         pgp_mpi_free(pk->pub.dsa.p);
      73            0 :                         pgp_mpi_free(pk->pub.dsa.q);
      74            0 :                         pgp_mpi_free(pk->pub.dsa.g);
      75            0 :                         pgp_mpi_free(pk->pub.dsa.y);
      76            0 :                         pgp_mpi_free(pk->sec.dsa.x);
      77            0 :                         break;
      78              :         }
      79            0 :         px_memset(pk, 0, sizeof(*pk));
      80            0 :         pfree(pk);
      81            0 : }
      82              : 
      83              : static int
      84            0 : calc_key_id(PGP_PubKey *pk)
      85              : {
      86            0 :         int                     res;
      87            0 :         PX_MD      *md;
      88            0 :         int                     len;
      89            0 :         uint8           hdr[3];
      90            0 :         uint8           hash[20];
      91              : 
      92            0 :         res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
      93            0 :         if (res < 0)
      94            0 :                 return res;
      95              : 
      96            0 :         len = 1 + 4 + 1;
      97            0 :         switch (pk->algo)
      98              :         {
      99              :                 case PGP_PUB_ELG_ENCRYPT:
     100            0 :                         len += 2 + pk->pub.elg.p->bytes;
     101            0 :                         len += 2 + pk->pub.elg.g->bytes;
     102            0 :                         len += 2 + pk->pub.elg.y->bytes;
     103            0 :                         break;
     104              :                 case PGP_PUB_RSA_SIGN:
     105              :                 case PGP_PUB_RSA_ENCRYPT:
     106              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     107            0 :                         len += 2 + pk->pub.rsa.n->bytes;
     108            0 :                         len += 2 + pk->pub.rsa.e->bytes;
     109            0 :                         break;
     110              :                 case PGP_PUB_DSA_SIGN:
     111            0 :                         len += 2 + pk->pub.dsa.p->bytes;
     112            0 :                         len += 2 + pk->pub.dsa.q->bytes;
     113            0 :                         len += 2 + pk->pub.dsa.g->bytes;
     114            0 :                         len += 2 + pk->pub.dsa.y->bytes;
     115            0 :                         break;
     116              :         }
     117              : 
     118            0 :         hdr[0] = 0x99;
     119            0 :         hdr[1] = len >> 8;
     120            0 :         hdr[2] = len & 0xFF;
     121            0 :         px_md_update(md, hdr, 3);
     122              : 
     123            0 :         px_md_update(md, &pk->ver, 1);
     124            0 :         px_md_update(md, pk->time, 4);
     125            0 :         px_md_update(md, &pk->algo, 1);
     126              : 
     127            0 :         switch (pk->algo)
     128              :         {
     129              :                 case PGP_PUB_ELG_ENCRYPT:
     130            0 :                         pgp_mpi_hash(md, pk->pub.elg.p);
     131            0 :                         pgp_mpi_hash(md, pk->pub.elg.g);
     132            0 :                         pgp_mpi_hash(md, pk->pub.elg.y);
     133            0 :                         break;
     134              :                 case PGP_PUB_RSA_SIGN:
     135              :                 case PGP_PUB_RSA_ENCRYPT:
     136              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     137            0 :                         pgp_mpi_hash(md, pk->pub.rsa.n);
     138            0 :                         pgp_mpi_hash(md, pk->pub.rsa.e);
     139            0 :                         break;
     140              :                 case PGP_PUB_DSA_SIGN:
     141            0 :                         pgp_mpi_hash(md, pk->pub.dsa.p);
     142            0 :                         pgp_mpi_hash(md, pk->pub.dsa.q);
     143            0 :                         pgp_mpi_hash(md, pk->pub.dsa.g);
     144            0 :                         pgp_mpi_hash(md, pk->pub.dsa.y);
     145            0 :                         break;
     146              :         }
     147              : 
     148            0 :         px_md_finish(md, hash);
     149            0 :         px_md_free(md);
     150              : 
     151            0 :         memcpy(pk->key_id, hash + 12, 8);
     152            0 :         px_memset(hash, 0, 20);
     153              : 
     154            0 :         return 0;
     155            0 : }
     156              : 
     157              : int
     158            0 : _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
     159              : {
     160            0 :         int                     res;
     161            0 :         PGP_PubKey *pk;
     162              : 
     163            0 :         res = pgp_key_alloc(&pk);
     164            0 :         if (res < 0)
     165            0 :                 return res;
     166              : 
     167              :         /* get version */
     168            0 :         GETBYTE(pkt, pk->ver);
     169            0 :         if (pk->ver != 4)
     170              :         {
     171            0 :                 res = PXE_PGP_NOT_V4_KEYPKT;
     172            0 :                 goto out;
     173              :         }
     174              : 
     175              :         /* read time */
     176            0 :         res = pullf_read_fixed(pkt, 4, pk->time);
     177            0 :         if (res < 0)
     178            0 :                 goto out;
     179              : 
     180              :         /* pubkey algorithm */
     181            0 :         GETBYTE(pkt, pk->algo);
     182              : 
     183            0 :         switch (pk->algo)
     184              :         {
     185              :                 case PGP_PUB_DSA_SIGN:
     186            0 :                         res = pgp_mpi_read(pkt, &pk->pub.dsa.p);
     187            0 :                         if (res < 0)
     188            0 :                                 break;
     189            0 :                         res = pgp_mpi_read(pkt, &pk->pub.dsa.q);
     190            0 :                         if (res < 0)
     191            0 :                                 break;
     192            0 :                         res = pgp_mpi_read(pkt, &pk->pub.dsa.g);
     193            0 :                         if (res < 0)
     194            0 :                                 break;
     195            0 :                         res = pgp_mpi_read(pkt, &pk->pub.dsa.y);
     196            0 :                         if (res < 0)
     197            0 :                                 break;
     198              : 
     199            0 :                         res = calc_key_id(pk);
     200            0 :                         break;
     201              : 
     202              :                 case PGP_PUB_RSA_SIGN:
     203              :                 case PGP_PUB_RSA_ENCRYPT:
     204              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     205            0 :                         res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
     206            0 :                         if (res < 0)
     207            0 :                                 break;
     208            0 :                         res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
     209            0 :                         if (res < 0)
     210            0 :                                 break;
     211              : 
     212            0 :                         res = calc_key_id(pk);
     213              : 
     214            0 :                         if (pk->algo != PGP_PUB_RSA_SIGN)
     215            0 :                                 pk->can_encrypt = 1;
     216            0 :                         break;
     217              : 
     218              :                 case PGP_PUB_ELG_ENCRYPT:
     219            0 :                         res = pgp_mpi_read(pkt, &pk->pub.elg.p);
     220            0 :                         if (res < 0)
     221            0 :                                 break;
     222            0 :                         res = pgp_mpi_read(pkt, &pk->pub.elg.g);
     223            0 :                         if (res < 0)
     224            0 :                                 break;
     225            0 :                         res = pgp_mpi_read(pkt, &pk->pub.elg.y);
     226            0 :                         if (res < 0)
     227            0 :                                 break;
     228              : 
     229            0 :                         res = calc_key_id(pk);
     230              : 
     231            0 :                         pk->can_encrypt = 1;
     232            0 :                         break;
     233              : 
     234              :                 default:
     235            0 :                         px_debug("unknown public algo: %d", pk->algo);
     236            0 :                         res = PXE_PGP_UNKNOWN_PUBALGO;
     237            0 :         }
     238              : 
     239              : out:
     240            0 :         if (res < 0)
     241            0 :                 pgp_key_free(pk);
     242              :         else
     243            0 :                 *pk_p = pk;
     244              : 
     245            0 :         return res;
     246            0 : }
     247              : 
     248              : #define HIDE_CLEAR 0
     249              : #define HIDE_CKSUM 255
     250              : #define HIDE_SHA1 254
     251              : 
     252              : static int
     253            0 : check_key_sha1(PullFilter *src, PGP_PubKey *pk)
     254              : {
     255            0 :         int                     res;
     256            0 :         uint8           got_sha1[20];
     257            0 :         uint8           my_sha1[20];
     258            0 :         PX_MD      *md;
     259              : 
     260            0 :         res = pullf_read_fixed(src, 20, got_sha1);
     261            0 :         if (res < 0)
     262            0 :                 return res;
     263              : 
     264            0 :         res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
     265            0 :         if (res < 0)
     266            0 :                 goto err;
     267            0 :         switch (pk->algo)
     268              :         {
     269              :                 case PGP_PUB_ELG_ENCRYPT:
     270            0 :                         pgp_mpi_hash(md, pk->sec.elg.x);
     271            0 :                         break;
     272              :                 case PGP_PUB_RSA_SIGN:
     273              :                 case PGP_PUB_RSA_ENCRYPT:
     274              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     275            0 :                         pgp_mpi_hash(md, pk->sec.rsa.d);
     276            0 :                         pgp_mpi_hash(md, pk->sec.rsa.p);
     277            0 :                         pgp_mpi_hash(md, pk->sec.rsa.q);
     278            0 :                         pgp_mpi_hash(md, pk->sec.rsa.u);
     279            0 :                         break;
     280              :                 case PGP_PUB_DSA_SIGN:
     281            0 :                         pgp_mpi_hash(md, pk->sec.dsa.x);
     282            0 :                         break;
     283              :         }
     284            0 :         px_md_finish(md, my_sha1);
     285            0 :         px_md_free(md);
     286              : 
     287            0 :         if (memcmp(my_sha1, got_sha1, 20) != 0)
     288              :         {
     289            0 :                 px_debug("key sha1 check failed");
     290            0 :                 res = PXE_PGP_KEYPKT_CORRUPT;
     291            0 :         }
     292              : err:
     293            0 :         px_memset(got_sha1, 0, 20);
     294            0 :         px_memset(my_sha1, 0, 20);
     295            0 :         return res;
     296            0 : }
     297              : 
     298              : static int
     299            0 : check_key_cksum(PullFilter *src, PGP_PubKey *pk)
     300              : {
     301            0 :         int                     res;
     302            0 :         unsigned        got_cksum,
     303            0 :                                 my_cksum = 0;
     304            0 :         uint8           buf[2];
     305              : 
     306            0 :         res = pullf_read_fixed(src, 2, buf);
     307            0 :         if (res < 0)
     308            0 :                 return res;
     309              : 
     310            0 :         got_cksum = ((unsigned) buf[0] << 8) + buf[1];
     311            0 :         switch (pk->algo)
     312              :         {
     313              :                 case PGP_PUB_ELG_ENCRYPT:
     314            0 :                         my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
     315            0 :                         break;
     316              :                 case PGP_PUB_RSA_SIGN:
     317              :                 case PGP_PUB_RSA_ENCRYPT:
     318              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     319            0 :                         my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
     320            0 :                         my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
     321            0 :                         my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
     322            0 :                         my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
     323            0 :                         break;
     324              :                 case PGP_PUB_DSA_SIGN:
     325            0 :                         my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
     326            0 :                         break;
     327              :         }
     328            0 :         if (my_cksum != got_cksum)
     329              :         {
     330            0 :                 px_debug("key cksum check failed");
     331            0 :                 return PXE_PGP_KEYPKT_CORRUPT;
     332              :         }
     333            0 :         return 0;
     334            0 : }
     335              : 
     336              : static int
     337            0 : process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
     338              :                                    const uint8 *key, int key_len)
     339              : {
     340            0 :         int                     res;
     341            0 :         int                     hide_type;
     342            0 :         int                     cipher_algo;
     343            0 :         int                     bs;
     344            0 :         uint8           iv[512];
     345            0 :         PullFilter *pf_decrypt = NULL,
     346              :                            *pf_key;
     347            0 :         PGP_CFB    *cfb = NULL;
     348            0 :         PGP_S2K         s2k;
     349            0 :         PGP_PubKey *pk;
     350              : 
     351              :         /* first read public key part */
     352            0 :         res = _pgp_read_public_key(pkt, &pk);
     353            0 :         if (res < 0)
     354            0 :                 return res;
     355              : 
     356              :         /*
     357              :          * is secret key encrypted?
     358              :          */
     359            0 :         GETBYTE(pkt, hide_type);
     360            0 :         if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
     361              :         {
     362            0 :                 if (key == NULL)
     363            0 :                         return PXE_PGP_NEED_SECRET_PSW;
     364            0 :                 GETBYTE(pkt, cipher_algo);
     365            0 :                 res = pgp_s2k_read(pkt, &s2k);
     366            0 :                 if (res < 0)
     367            0 :                         return res;
     368              : 
     369            0 :                 res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
     370            0 :                 if (res < 0)
     371            0 :                         return res;
     372              : 
     373            0 :                 bs = pgp_get_cipher_block_size(cipher_algo);
     374            0 :                 if (bs == 0)
     375              :                 {
     376            0 :                         px_debug("unknown cipher algo=%d", cipher_algo);
     377            0 :                         return PXE_PGP_UNSUPPORTED_CIPHER;
     378              :                 }
     379            0 :                 res = pullf_read_fixed(pkt, bs, iv);
     380            0 :                 if (res < 0)
     381            0 :                         return res;
     382              : 
     383              :                 /*
     384              :                  * create decrypt filter
     385              :                  */
     386            0 :                 res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
     387            0 :                 if (res < 0)
     388            0 :                         return res;
     389            0 :                 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
     390            0 :                 if (res < 0)
     391            0 :                         return res;
     392            0 :                 pf_key = pf_decrypt;
     393            0 :         }
     394            0 :         else if (hide_type == HIDE_CLEAR)
     395              :         {
     396            0 :                 pf_key = pkt;
     397            0 :         }
     398              :         else
     399              :         {
     400            0 :                 px_debug("unknown hide type");
     401            0 :                 return PXE_PGP_KEYPKT_CORRUPT;
     402              :         }
     403              : 
     404              :         /* read secret key */
     405            0 :         switch (pk->algo)
     406              :         {
     407              :                 case PGP_PUB_RSA_SIGN:
     408              :                 case PGP_PUB_RSA_ENCRYPT:
     409              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     410            0 :                         res = pgp_mpi_read(pf_key, &pk->sec.rsa.d);
     411            0 :                         if (res < 0)
     412            0 :                                 break;
     413            0 :                         res = pgp_mpi_read(pf_key, &pk->sec.rsa.p);
     414            0 :                         if (res < 0)
     415            0 :                                 break;
     416            0 :                         res = pgp_mpi_read(pf_key, &pk->sec.rsa.q);
     417            0 :                         if (res < 0)
     418            0 :                                 break;
     419            0 :                         res = pgp_mpi_read(pf_key, &pk->sec.rsa.u);
     420            0 :                         if (res < 0)
     421            0 :                                 break;
     422            0 :                         break;
     423              :                 case PGP_PUB_ELG_ENCRYPT:
     424            0 :                         res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
     425            0 :                         break;
     426              :                 case PGP_PUB_DSA_SIGN:
     427            0 :                         res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
     428            0 :                         break;
     429              :                 default:
     430            0 :                         px_debug("unknown public algo: %d", pk->algo);
     431            0 :                         res = PXE_PGP_KEYPKT_CORRUPT;
     432            0 :         }
     433              :         /* read checksum / sha1 */
     434            0 :         if (res >= 0)
     435              :         {
     436            0 :                 if (hide_type == HIDE_SHA1)
     437            0 :                         res = check_key_sha1(pf_key, pk);
     438              :                 else
     439            0 :                         res = check_key_cksum(pf_key, pk);
     440            0 :         }
     441            0 :         if (res >= 0)
     442            0 :                 res = pgp_expect_packet_end(pf_key);
     443              : 
     444            0 :         if (pf_decrypt)
     445            0 :                 pullf_free(pf_decrypt);
     446            0 :         if (cfb)
     447            0 :                 pgp_cfb_free(cfb);
     448              : 
     449            0 :         if (res < 0)
     450            0 :                 pgp_key_free(pk);
     451              :         else
     452            0 :                 *pk_p = pk;
     453              : 
     454            0 :         return res;
     455            0 : }
     456              : 
     457              : static int
     458            0 : internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
     459              :                                   const uint8 *psw, int psw_len, int pubtype)
     460              : {
     461            0 :         PullFilter *pkt = NULL;
     462            0 :         int                     res;
     463            0 :         uint8           tag;
     464            0 :         int                     len;
     465            0 :         PGP_PubKey *enc_key = NULL;
     466            0 :         PGP_PubKey *pk = NULL;
     467            0 :         int                     got_main_key = 0;
     468              : 
     469              :         /*
     470              :          * Search for encryption key.
     471              :          *
     472              :          * Error out on anything fancy.
     473              :          */
     474            0 :         while (1)
     475              :         {
     476            0 :                 res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
     477            0 :                 if (res <= 0)
     478            0 :                         break;
     479            0 :                 res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
     480            0 :                 if (res < 0)
     481            0 :                         break;
     482              : 
     483            0 :                 switch (tag)
     484              :                 {
     485              :                         case PGP_PKT_PUBLIC_KEY:
     486              :                         case PGP_PKT_SECRET_KEY:
     487            0 :                                 if (got_main_key)
     488              :                                 {
     489            0 :                                         res = PXE_PGP_MULTIPLE_KEYS;
     490            0 :                                         break;
     491              :                                 }
     492            0 :                                 got_main_key = 1;
     493            0 :                                 res = pgp_skip_packet(pkt);
     494            0 :                                 break;
     495              : 
     496              :                         case PGP_PKT_PUBLIC_SUBKEY:
     497            0 :                                 if (pubtype != 0)
     498            0 :                                         res = PXE_PGP_EXPECT_SECRET_KEY;
     499              :                                 else
     500            0 :                                         res = _pgp_read_public_key(pkt, &pk);
     501            0 :                                 break;
     502              : 
     503              :                         case PGP_PKT_SECRET_SUBKEY:
     504            0 :                                 if (pubtype != 1)
     505            0 :                                         res = PXE_PGP_EXPECT_PUBLIC_KEY;
     506              :                                 else
     507            0 :                                         res = process_secret_key(pkt, &pk, psw, psw_len);
     508            0 :                                 break;
     509              : 
     510              :                         case PGP_PKT_SIGNATURE:
     511              :                         case PGP_PKT_MARKER:
     512              :                         case PGP_PKT_TRUST:
     513              :                         case PGP_PKT_USER_ID:
     514              :                         case PGP_PKT_USER_ATTR:
     515              :                         case PGP_PKT_PRIV_61:
     516            0 :                                 res = pgp_skip_packet(pkt);
     517            0 :                                 break;
     518              :                         default:
     519            0 :                                 px_debug("unknown/unexpected packet: %d", tag);
     520            0 :                                 res = PXE_PGP_UNEXPECTED_PKT;
     521            0 :                 }
     522            0 :                 pullf_free(pkt);
     523            0 :                 pkt = NULL;
     524              : 
     525            0 :                 if (pk != NULL)
     526              :                 {
     527            0 :                         if (res >= 0 && pk->can_encrypt)
     528              :                         {
     529            0 :                                 if (enc_key == NULL)
     530              :                                 {
     531            0 :                                         enc_key = pk;
     532            0 :                                         pk = NULL;
     533            0 :                                 }
     534              :                                 else
     535            0 :                                         res = PXE_PGP_MULTIPLE_SUBKEYS;
     536            0 :                         }
     537              : 
     538            0 :                         if (pk)
     539            0 :                                 pgp_key_free(pk);
     540            0 :                         pk = NULL;
     541            0 :                 }
     542              : 
     543            0 :                 if (res < 0)
     544            0 :                         break;
     545              :         }
     546              : 
     547            0 :         if (pkt)
     548            0 :                 pullf_free(pkt);
     549              : 
     550            0 :         if (res < 0)
     551              :         {
     552            0 :                 if (enc_key)
     553            0 :                         pgp_key_free(enc_key);
     554            0 :                 return res;
     555              :         }
     556              : 
     557            0 :         if (!enc_key)
     558            0 :                 res = PXE_PGP_NO_USABLE_KEY;
     559              :         else
     560            0 :                 *pk_p = enc_key;
     561            0 :         return res;
     562            0 : }
     563              : 
     564              : int
     565            0 : pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
     566              :                            const uint8 *key, int key_len, int pubtype)
     567              : {
     568            0 :         int                     res;
     569            0 :         PullFilter *src;
     570            0 :         PGP_PubKey *pk = NULL;
     571              : 
     572            0 :         res = pullf_create_mbuf_reader(&src, keypkt);
     573            0 :         if (res < 0)
     574            0 :                 return res;
     575              : 
     576            0 :         res = internal_read_key(src, &pk, key, key_len, pubtype);
     577            0 :         pullf_free(src);
     578              : 
     579            0 :         if (res >= 0)
     580            0 :                 ctx->pub_key = pk;
     581              : 
     582            0 :         return res < 0 ? res : 0;
     583            0 : }
        

Generated by: LCOV version 2.3.2-1