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

Generated by: LCOV version 1.13