LCOV - code coverage report
Current view: top level - contrib/pgcrypto - pgp-pubkey.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 72.1 % 333 240
Test Date: 2026-03-04 08:14:57 Functions: 100.0 % 9 9
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           34 : pgp_key_alloc(PGP_PubKey **pk_p)
      39              : {
      40              :     PGP_PubKey *pk;
      41              : 
      42           34 :     pk = palloc0_object(PGP_PubKey);
      43           34 :     *pk_p = pk;
      44           34 :     return 0;
      45              : }
      46              : 
      47              : void
      48           33 : pgp_key_free(PGP_PubKey *pk)
      49              : {
      50           33 :     if (pk == NULL)
      51            0 :         return;
      52              : 
      53           33 :     switch (pk->algo)
      54              :     {
      55           24 :         case PGP_PUB_ELG_ENCRYPT:
      56           24 :             pgp_mpi_free(pk->pub.elg.p);
      57           24 :             pgp_mpi_free(pk->pub.elg.g);
      58           24 :             pgp_mpi_free(pk->pub.elg.y);
      59           24 :             pgp_mpi_free(pk->sec.elg.x);
      60           24 :             break;
      61            9 :         case PGP_PUB_RSA_SIGN:
      62              :         case PGP_PUB_RSA_ENCRYPT:
      63              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
      64            9 :             pgp_mpi_free(pk->pub.rsa.n);
      65            9 :             pgp_mpi_free(pk->pub.rsa.e);
      66            9 :             pgp_mpi_free(pk->sec.rsa.d);
      67            9 :             pgp_mpi_free(pk->sec.rsa.p);
      68            9 :             pgp_mpi_free(pk->sec.rsa.q);
      69            9 :             pgp_mpi_free(pk->sec.rsa.u);
      70            9 :             break;
      71            0 :         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           33 :     px_memset(pk, 0, sizeof(*pk));
      80           33 :     pfree(pk);
      81              : }
      82              : 
      83              : static int
      84           34 : calc_key_id(PGP_PubKey *pk)
      85              : {
      86              :     int         res;
      87              :     PX_MD      *md;
      88              :     int         len;
      89              :     uint8       hdr[3];
      90              :     uint8       hash[20];
      91              : 
      92           34 :     res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
      93           34 :     if (res < 0)
      94            0 :         return res;
      95              : 
      96           34 :     len = 1 + 4 + 1;
      97           34 :     switch (pk->algo)
      98              :     {
      99           25 :         case PGP_PUB_ELG_ENCRYPT:
     100           25 :             len += 2 + pk->pub.elg.p->bytes;
     101           25 :             len += 2 + pk->pub.elg.g->bytes;
     102           25 :             len += 2 + pk->pub.elg.y->bytes;
     103           25 :             break;
     104            9 :         case PGP_PUB_RSA_SIGN:
     105              :         case PGP_PUB_RSA_ENCRYPT:
     106              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
     107            9 :             len += 2 + pk->pub.rsa.n->bytes;
     108            9 :             len += 2 + pk->pub.rsa.e->bytes;
     109            9 :             break;
     110            0 :         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           34 :     hdr[0] = 0x99;
     119           34 :     hdr[1] = len >> 8;
     120           34 :     hdr[2] = len & 0xFF;
     121           34 :     px_md_update(md, hdr, 3);
     122              : 
     123           34 :     px_md_update(md, &pk->ver, 1);
     124           34 :     px_md_update(md, pk->time, 4);
     125           34 :     px_md_update(md, &pk->algo, 1);
     126              : 
     127           34 :     switch (pk->algo)
     128              :     {
     129           25 :         case PGP_PUB_ELG_ENCRYPT:
     130           25 :             pgp_mpi_hash(md, pk->pub.elg.p);
     131           25 :             pgp_mpi_hash(md, pk->pub.elg.g);
     132           25 :             pgp_mpi_hash(md, pk->pub.elg.y);
     133           25 :             break;
     134            9 :         case PGP_PUB_RSA_SIGN:
     135              :         case PGP_PUB_RSA_ENCRYPT:
     136              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
     137            9 :             pgp_mpi_hash(md, pk->pub.rsa.n);
     138            9 :             pgp_mpi_hash(md, pk->pub.rsa.e);
     139            9 :             break;
     140            0 :         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           34 :     px_md_finish(md, hash);
     149           34 :     px_md_free(md);
     150              : 
     151           34 :     memcpy(pk->key_id, hash + 12, 8);
     152           34 :     px_memset(hash, 0, 20);
     153              : 
     154           34 :     return 0;
     155              : }
     156              : 
     157              : int
     158           34 : _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p)
     159              : {
     160              :     int         res;
     161              :     PGP_PubKey *pk;
     162              : 
     163           34 :     res = pgp_key_alloc(&pk);
     164           34 :     if (res < 0)
     165            0 :         return res;
     166              : 
     167              :     /* get version */
     168           34 :     GETBYTE(pkt, pk->ver);
     169           34 :     if (pk->ver != 4)
     170              :     {
     171            0 :         res = PXE_PGP_NOT_V4_KEYPKT;
     172            0 :         goto out;
     173              :     }
     174              : 
     175              :     /* read time */
     176           34 :     res = pullf_read_fixed(pkt, 4, pk->time);
     177           34 :     if (res < 0)
     178            0 :         goto out;
     179              : 
     180              :     /* pubkey algorithm */
     181           34 :     GETBYTE(pkt, pk->algo);
     182              : 
     183           34 :     switch (pk->algo)
     184              :     {
     185            0 :         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            9 :         case PGP_PUB_RSA_SIGN:
     203              :         case PGP_PUB_RSA_ENCRYPT:
     204              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
     205            9 :             res = pgp_mpi_read(pkt, &pk->pub.rsa.n);
     206            9 :             if (res < 0)
     207            0 :                 break;
     208            9 :             res = pgp_mpi_read(pkt, &pk->pub.rsa.e);
     209            9 :             if (res < 0)
     210            0 :                 break;
     211              : 
     212            9 :             res = calc_key_id(pk);
     213              : 
     214            9 :             if (pk->algo != PGP_PUB_RSA_SIGN)
     215            9 :                 pk->can_encrypt = 1;
     216            9 :             break;
     217              : 
     218           25 :         case PGP_PUB_ELG_ENCRYPT:
     219           25 :             res = pgp_mpi_read(pkt, &pk->pub.elg.p);
     220           25 :             if (res < 0)
     221            0 :                 break;
     222           25 :             res = pgp_mpi_read(pkt, &pk->pub.elg.g);
     223           25 :             if (res < 0)
     224            0 :                 break;
     225           25 :             res = pgp_mpi_read(pkt, &pk->pub.elg.y);
     226           25 :             if (res < 0)
     227            0 :                 break;
     228              : 
     229           25 :             res = calc_key_id(pk);
     230              : 
     231           25 :             pk->can_encrypt = 1;
     232           25 :             break;
     233              : 
     234            0 :         default:
     235            0 :             px_debug("unknown public algo: %d", pk->algo);
     236            0 :             res = PXE_PGP_UNKNOWN_PUBALGO;
     237              :     }
     238              : 
     239           34 : out:
     240           34 :     if (res < 0)
     241            0 :         pgp_key_free(pk);
     242              :     else
     243           34 :         *pk_p = pk;
     244              : 
     245           34 :     return res;
     246              : }
     247              : 
     248              : #define HIDE_CLEAR 0
     249              : #define HIDE_CKSUM 255
     250              : #define HIDE_SHA1 254
     251              : 
     252              : static int
     253            2 : check_key_sha1(PullFilter *src, PGP_PubKey *pk)
     254              : {
     255              :     int         res;
     256              :     uint8       got_sha1[20];
     257              :     uint8       my_sha1[20];
     258              :     PX_MD      *md;
     259              : 
     260            2 :     res = pullf_read_fixed(src, 20, got_sha1);
     261            2 :     if (res < 0)
     262            0 :         return res;
     263              : 
     264            2 :     res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
     265            2 :     if (res < 0)
     266            0 :         goto err;
     267            2 :     switch (pk->algo)
     268              :     {
     269            1 :         case PGP_PUB_ELG_ENCRYPT:
     270            1 :             pgp_mpi_hash(md, pk->sec.elg.x);
     271            1 :             break;
     272            1 :         case PGP_PUB_RSA_SIGN:
     273              :         case PGP_PUB_RSA_ENCRYPT:
     274              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
     275            1 :             pgp_mpi_hash(md, pk->sec.rsa.d);
     276            1 :             pgp_mpi_hash(md, pk->sec.rsa.p);
     277            1 :             pgp_mpi_hash(md, pk->sec.rsa.q);
     278            1 :             pgp_mpi_hash(md, pk->sec.rsa.u);
     279            1 :             break;
     280            0 :         case PGP_PUB_DSA_SIGN:
     281            0 :             pgp_mpi_hash(md, pk->sec.dsa.x);
     282            0 :             break;
     283              :     }
     284            2 :     px_md_finish(md, my_sha1);
     285            2 :     px_md_free(md);
     286              : 
     287            2 :     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              :     }
     292            2 : err:
     293            2 :     px_memset(got_sha1, 0, 20);
     294            2 :     px_memset(my_sha1, 0, 20);
     295            2 :     return res;
     296              : }
     297              : 
     298              : static int
     299           13 : check_key_cksum(PullFilter *src, PGP_PubKey *pk)
     300              : {
     301              :     int         res;
     302              :     unsigned    got_cksum,
     303           13 :                 my_cksum = 0;
     304              :     uint8       buf[2];
     305              : 
     306           13 :     res = pullf_read_fixed(src, 2, buf);
     307           13 :     if (res < 0)
     308            0 :         return res;
     309              : 
     310           13 :     got_cksum = ((unsigned) buf[0] << 8) + buf[1];
     311           13 :     switch (pk->algo)
     312              :     {
     313            9 :         case PGP_PUB_ELG_ENCRYPT:
     314            9 :             my_cksum = pgp_mpi_cksum(0, pk->sec.elg.x);
     315            9 :             break;
     316            4 :         case PGP_PUB_RSA_SIGN:
     317              :         case PGP_PUB_RSA_ENCRYPT:
     318              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
     319            4 :             my_cksum = pgp_mpi_cksum(0, pk->sec.rsa.d);
     320            4 :             my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.p);
     321            4 :             my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.q);
     322            4 :             my_cksum = pgp_mpi_cksum(my_cksum, pk->sec.rsa.u);
     323            4 :             break;
     324            0 :         case PGP_PUB_DSA_SIGN:
     325            0 :             my_cksum = pgp_mpi_cksum(0, pk->sec.dsa.x);
     326            0 :             break;
     327              :     }
     328           13 :     if (my_cksum != got_cksum)
     329              :     {
     330            0 :         px_debug("key cksum check failed");
     331            0 :         return PXE_PGP_KEYPKT_CORRUPT;
     332              :     }
     333           13 :     return 0;
     334              : }
     335              : 
     336              : static int
     337           18 : process_secret_key(PullFilter *pkt, PGP_PubKey **pk_p,
     338              :                    const uint8 *key, int key_len)
     339              : {
     340              :     int         res;
     341              :     int         hide_type;
     342              :     int         cipher_algo;
     343              :     int         bs;
     344              :     uint8       iv[512];
     345           18 :     PullFilter *pf_decrypt = NULL,
     346              :                *pf_key;
     347           18 :     PGP_CFB    *cfb = NULL;
     348              :     PGP_S2K     s2k;
     349              :     PGP_PubKey *pk;
     350              : 
     351              :     /* first read public key part */
     352           18 :     res = _pgp_read_public_key(pkt, &pk);
     353           18 :     if (res < 0)
     354            0 :         return res;
     355              : 
     356              :     /*
     357              :      * is secret key encrypted?
     358              :      */
     359           18 :     GETBYTE(pkt, hide_type);
     360           18 :     if (hide_type == HIDE_SHA1 || hide_type == HIDE_CKSUM)
     361              :     {
     362            5 :         if (key == NULL)
     363            1 :             return PXE_PGP_NEED_SECRET_PSW;
     364            4 :         GETBYTE(pkt, cipher_algo);
     365            4 :         res = pgp_s2k_read(pkt, &s2k);
     366            4 :         if (res < 0)
     367            0 :             return res;
     368              : 
     369            4 :         res = pgp_s2k_process(&s2k, cipher_algo, key, key_len);
     370            4 :         if (res < 0)
     371            0 :             return res;
     372              : 
     373            4 :         bs = pgp_get_cipher_block_size(cipher_algo);
     374            4 :         if (bs == 0)
     375              :         {
     376            0 :             px_debug("unknown cipher algo=%d", cipher_algo);
     377            0 :             return PXE_PGP_UNSUPPORTED_CIPHER;
     378              :         }
     379            4 :         res = pullf_read_fixed(pkt, bs, iv);
     380            4 :         if (res < 0)
     381            0 :             return res;
     382              : 
     383              :         /*
     384              :          * create decrypt filter
     385              :          */
     386            4 :         res = pgp_cfb_create(&cfb, cipher_algo, s2k.key, s2k.key_len, 0, iv);
     387            4 :         if (res < 0)
     388            0 :             return res;
     389            4 :         res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
     390            4 :         if (res < 0)
     391            0 :             return res;
     392            4 :         pf_key = pf_decrypt;
     393              :     }
     394           13 :     else if (hide_type == HIDE_CLEAR)
     395              :     {
     396           13 :         pf_key = pkt;
     397              :     }
     398              :     else
     399              :     {
     400            0 :         px_debug("unknown hide type");
     401            0 :         return PXE_PGP_KEYPKT_CORRUPT;
     402              :     }
     403              : 
     404              :     /* read secret key */
     405           17 :     switch (pk->algo)
     406              :     {
     407            6 :         case PGP_PUB_RSA_SIGN:
     408              :         case PGP_PUB_RSA_ENCRYPT:
     409              :         case PGP_PUB_RSA_ENCRYPT_SIGN:
     410            6 :             res = pgp_mpi_read(pf_key, &pk->sec.rsa.d);
     411            6 :             if (res < 0)
     412            0 :                 break;
     413            6 :             res = pgp_mpi_read(pf_key, &pk->sec.rsa.p);
     414            6 :             if (res < 0)
     415            1 :                 break;
     416            5 :             res = pgp_mpi_read(pf_key, &pk->sec.rsa.q);
     417            5 :             if (res < 0)
     418            0 :                 break;
     419            5 :             res = pgp_mpi_read(pf_key, &pk->sec.rsa.u);
     420            5 :             if (res < 0)
     421            0 :                 break;
     422            5 :             break;
     423           11 :         case PGP_PUB_ELG_ENCRYPT:
     424           11 :             res = pgp_mpi_read(pf_key, &pk->sec.elg.x);
     425           11 :             break;
     426            0 :         case PGP_PUB_DSA_SIGN:
     427            0 :             res = pgp_mpi_read(pf_key, &pk->sec.dsa.x);
     428            0 :             break;
     429            0 :         default:
     430            0 :             px_debug("unknown public algo: %d", pk->algo);
     431            0 :             res = PXE_PGP_KEYPKT_CORRUPT;
     432              :     }
     433              :     /* read checksum / sha1 */
     434           17 :     if (res >= 0)
     435              :     {
     436           15 :         if (hide_type == HIDE_SHA1)
     437            2 :             res = check_key_sha1(pf_key, pk);
     438              :         else
     439           13 :             res = check_key_cksum(pf_key, pk);
     440              :     }
     441           17 :     if (res >= 0)
     442           15 :         res = pgp_expect_packet_end(pf_key);
     443              : 
     444           17 :     if (pf_decrypt)
     445            4 :         pullf_free(pf_decrypt);
     446           17 :     if (cfb)
     447            4 :         pgp_cfb_free(cfb);
     448              : 
     449           17 :     if (res < 0)
     450            2 :         pgp_key_free(pk);
     451              :     else
     452           15 :         *pk_p = pk;
     453              : 
     454           17 :     return res;
     455              : }
     456              : 
     457              : static int
     458           27 : internal_read_key(PullFilter *src, PGP_PubKey **pk_p,
     459              :                   const uint8 *psw, int psw_len, int pubtype)
     460              : {
     461           27 :     PullFilter *pkt = NULL;
     462              :     int         res;
     463              :     uint8       tag;
     464              :     int         len;
     465           27 :     PGP_PubKey *enc_key = NULL;
     466           27 :     PGP_PubKey *pk = NULL;
     467           27 :     int         got_main_key = 0;
     468              : 
     469              :     /*
     470              :      * Search for encryption key.
     471              :      *
     472              :      * Error out on anything fancy.
     473              :      */
     474              :     while (1)
     475              :     {
     476          146 :         res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
     477          146 :         if (res <= 0)
     478           23 :             break;
     479          123 :         res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
     480          123 :         if (res < 0)
     481            0 :             break;
     482              : 
     483          123 :         switch (tag)
     484              :         {
     485           26 :             case PGP_PKT_PUBLIC_KEY:
     486              :             case PGP_PKT_SECRET_KEY:
     487           26 :                 if (got_main_key)
     488              :                 {
     489            0 :                     res = PXE_PGP_MULTIPLE_KEYS;
     490            0 :                     break;
     491              :                 }
     492           26 :                 got_main_key = 1;
     493           26 :                 res = pgp_skip_packet(pkt);
     494           26 :                 break;
     495              : 
     496            6 :             case PGP_PKT_PUBLIC_SUBKEY:
     497            6 :                 if (pubtype != 0)
     498            0 :                     res = PXE_PGP_EXPECT_SECRET_KEY;
     499              :                 else
     500            6 :                     res = _pgp_read_public_key(pkt, &pk);
     501            6 :                 break;
     502              : 
     503           19 :             case PGP_PKT_SECRET_SUBKEY:
     504           19 :                 if (pubtype != 1)
     505            1 :                     res = PXE_PGP_EXPECT_PUBLIC_KEY;
     506              :                 else
     507           18 :                     res = process_secret_key(pkt, &pk, psw, psw_len);
     508           19 :                 break;
     509              : 
     510           72 :             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           72 :                 res = pgp_skip_packet(pkt);
     517           72 :                 break;
     518            0 :             default:
     519            0 :                 px_debug("unknown/unexpected packet: %d", tag);
     520            0 :                 res = PXE_PGP_UNEXPECTED_PKT;
     521              :         }
     522          123 :         pullf_free(pkt);
     523          123 :         pkt = NULL;
     524              : 
     525          123 :         if (pk != NULL)
     526              :         {
     527           21 :             if (res >= 0 && pk->can_encrypt)
     528              :             {
     529           21 :                 if (enc_key == NULL)
     530              :                 {
     531           21 :                     enc_key = pk;
     532           21 :                     pk = NULL;
     533              :                 }
     534              :                 else
     535            0 :                     res = PXE_PGP_MULTIPLE_SUBKEYS;
     536              :             }
     537              : 
     538           21 :             if (pk)
     539            0 :                 pgp_key_free(pk);
     540           21 :             pk = NULL;
     541              :         }
     542              : 
     543          123 :         if (res < 0)
     544            4 :             break;
     545              :     }
     546              : 
     547           27 :     if (pkt)
     548            0 :         pullf_free(pkt);
     549              : 
     550           27 :     if (res < 0)
     551              :     {
     552            4 :         if (enc_key)
     553            0 :             pgp_key_free(enc_key);
     554            4 :         return res;
     555              :     }
     556              : 
     557           23 :     if (!enc_key)
     558            2 :         res = PXE_PGP_NO_USABLE_KEY;
     559              :     else
     560           21 :         *pk_p = enc_key;
     561           23 :     return res;
     562              : }
     563              : 
     564              : int
     565           27 : pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt,
     566              :                const uint8 *key, int key_len, int pubtype)
     567              : {
     568              :     int         res;
     569              :     PullFilter *src;
     570           27 :     PGP_PubKey *pk = NULL;
     571              : 
     572           27 :     res = pullf_create_mbuf_reader(&src, keypkt);
     573           27 :     if (res < 0)
     574            0 :         return res;
     575              : 
     576           27 :     res = internal_read_key(src, &pk, key, key_len, pubtype);
     577           27 :     pullf_free(src);
     578              : 
     579           27 :     if (res >= 0)
     580           21 :         ctx->pub_key = pk;
     581              : 
     582           27 :     return res < 0 ? res : 0;
     583              : }
        

Generated by: LCOV version 2.0-1