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

Generated by: LCOV version 1.14