LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgp-info.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 77.7 % 103 80 23 80
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 4 4 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*
       2                 :  * pgp-info.c
       3                 :  *    Provide info about PGP data.
       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-info.c
      30                 :  */
      31                 : #include "postgres.h"
      32                 : 
      33                 : #include "mbuf.h"
      34                 : #include "pgp.h"
      35                 : #include "px.h"
      36                 : 
      37                 : static int
      38 CBC          10 : read_pubkey_keyid(PullFilter *pkt, uint8 *keyid_buf)
      39                 : {
      40                 :     int         res;
      41              10 :     PGP_PubKey *pk = NULL;
      42                 : 
      43              10 :     res = _pgp_read_public_key(pkt, &pk);
      44              10 :     if (res < 0)
      45 UBC           0 :         goto err;
      46                 : 
      47                 :     /* skip secret key part, if it exists */
      48 CBC          10 :     res = pgp_skip_packet(pkt);
      49              10 :     if (res < 0)
      50 UBC           0 :         goto err;
      51                 : 
      52                 :     /* is it encryption key */
      53 CBC          10 :     switch (pk->algo)
      54                 :     {
      55              10 :         case PGP_PUB_ELG_ENCRYPT:
      56                 :         case PGP_PUB_RSA_ENCRYPT:
      57                 :         case PGP_PUB_RSA_ENCRYPT_SIGN:
      58              10 :             memcpy(keyid_buf, pk->key_id, 8);
      59              10 :             res = 1;
      60              10 :             break;
      61 UBC           0 :         default:
      62               0 :             res = 0;
      63                 :     }
      64                 : 
      65 CBC          10 : err:
      66              10 :     pgp_key_free(pk);
      67              10 :     return res;
      68                 : }
      69                 : 
      70                 : static int
      71               5 : read_pubenc_keyid(PullFilter *pkt, uint8 *keyid_buf)
      72                 : {
      73                 :     uint8       ver;
      74                 :     int         res;
      75                 : 
      76               5 :     GETBYTE(pkt, ver);
      77               5 :     if (ver != 3)
      78 UBC           0 :         return -1;
      79                 : 
      80 CBC           5 :     res = pullf_read_fixed(pkt, 8, keyid_buf);
      81               5 :     if (res < 0)
      82 UBC           0 :         return res;
      83                 : 
      84 CBC           5 :     return pgp_skip_packet(pkt);
      85                 : }
      86                 : 
      87                 : static const char hextbl[] = "0123456789ABCDEF";
      88                 : 
      89                 : static int
      90              15 : print_key(uint8 *keyid, char *dst)
      91                 : {
      92                 :     int         i;
      93                 :     unsigned    c;
      94                 : 
      95             135 :     for (i = 0; i < 8; i++)
      96                 :     {
      97             120 :         c = keyid[i];
      98             120 :         *dst++ = hextbl[(c >> 4) & 0x0F];
      99             120 :         *dst++ = hextbl[c & 0x0F];
     100                 :     }
     101              15 :     *dst = 0;
     102              15 :     return 8 * 2;
     103                 : }
     104                 : 
     105                 : static const uint8 any_key[] =
     106                 : {0, 0, 0, 0, 0, 0, 0, 0};
     107                 : 
     108                 : /*
     109                 :  * dst should have room for 17 bytes
     110                 :  */
     111                 : int
     112              17 : pgp_get_keyid(MBuf *pgp_data, char *dst)
     113                 : {
     114                 :     int         res;
     115                 :     PullFilter *src;
     116              17 :     PullFilter *pkt = NULL;
     117                 :     int         len;
     118                 :     uint8       tag;
     119              17 :     int         got_pub_key = 0,
     120              17 :                 got_symenc_key = 0,
     121              17 :                 got_pubenc_key = 0;
     122              17 :     int         got_data = 0;
     123                 :     uint8       keyid_buf[8];
     124              17 :     int         got_main_key = 0;
     125                 : 
     126                 : 
     127              17 :     res = pullf_create_mbuf_reader(&src, pgp_data);
     128              17 :     if (res < 0)
     129 UBC           0 :         return res;
     130                 : 
     131                 :     while (1)
     132                 :     {
     133 CBC          78 :         res = pgp_parse_pkt_hdr(src, &tag, &len, 0);
     134              78 :         if (res <= 0)
     135              12 :             break;
     136              66 :         res = pgp_create_pkt_reader(&pkt, src, len, res, NULL);
     137              66 :         if (res < 0)
     138 UBC           0 :             break;
     139                 : 
     140 CBC          66 :         switch (tag)
     141                 :         {
     142              12 :             case PGP_PKT_SECRET_KEY:
     143                 :             case PGP_PKT_PUBLIC_KEY:
     144                 :                 /* main key is for signing, so ignore it */
     145              12 :                 if (!got_main_key)
     146                 :                 {
     147              12 :                     got_main_key = 1;
     148              12 :                     res = pgp_skip_packet(pkt);
     149                 :                 }
     150                 :                 else
     151 UBC           0 :                     res = PXE_PGP_MULTIPLE_KEYS;
     152 CBC          12 :                 break;
     153              10 :             case PGP_PKT_SECRET_SUBKEY:
     154                 :             case PGP_PKT_PUBLIC_SUBKEY:
     155              10 :                 res = read_pubkey_keyid(pkt, keyid_buf);
     156              10 :                 if (res < 0)
     157 UBC           0 :                     break;
     158 CBC          10 :                 if (res > 0)
     159              10 :                     got_pub_key++;
     160              10 :                 break;
     161               5 :             case PGP_PKT_PUBENCRYPTED_SESSKEY:
     162               5 :                 got_pubenc_key++;
     163               5 :                 res = read_pubenc_keyid(pkt, keyid_buf);
     164               5 :                 break;
     165               5 :             case PGP_PKT_SYMENCRYPTED_DATA:
     166                 :             case PGP_PKT_SYMENCRYPTED_DATA_MDC:
     167                 :                 /* don't skip it, just stop */
     168               5 :                 got_data = 1;
     169               5 :                 break;
     170 UBC           0 :             case PGP_PKT_SYMENCRYPTED_SESSKEY:
     171               0 :                 got_symenc_key++;
     172                 :                 /* fall through */
     173 CBC          34 :             case PGP_PKT_SIGNATURE:
     174                 :             case PGP_PKT_MARKER:
     175                 :             case PGP_PKT_TRUST:
     176                 :             case PGP_PKT_USER_ID:
     177                 :             case PGP_PKT_USER_ATTR:
     178                 :             case PGP_PKT_PRIV_61:
     179              34 :                 res = pgp_skip_packet(pkt);
     180              34 :                 break;
     181 UBC           0 :             default:
     182               0 :                 res = PXE_PGP_CORRUPT_DATA;
     183                 :         }
     184                 : 
     185 CBC          66 :         if (pkt)
     186              66 :             pullf_free(pkt);
     187              66 :         pkt = NULL;
     188                 : 
     189              66 :         if (res < 0 || got_data)
     190                 :             break;
     191                 :     }
     192                 : 
     193              17 :     pullf_free(src);
     194              17 :     if (pkt)
     195 UBC           0 :         pullf_free(pkt);
     196                 : 
     197 CBC          17 :     if (res < 0)
     198 UBC           0 :         return res;
     199                 : 
     200                 :     /* now check sanity */
     201 CBC          17 :     if (got_pub_key && got_pubenc_key)
     202 UBC           0 :         res = PXE_PGP_CORRUPT_DATA;
     203                 : 
     204 CBC          17 :     if (got_pub_key > 1)
     205 UBC           0 :         res = PXE_PGP_MULTIPLE_KEYS;
     206                 : 
     207 CBC          17 :     if (got_pubenc_key > 1)
     208 UBC           0 :         res = PXE_PGP_MULTIPLE_KEYS;
     209                 : 
     210                 :     /*
     211                 :      * if still ok, look what we got
     212                 :      */
     213 CBC          17 :     if (res >= 0)
     214                 :     {
     215              17 :         if (got_pubenc_key || got_pub_key)
     216                 :         {
     217              15 :             if (memcmp(keyid_buf, any_key, 8) == 0)
     218                 :             {
     219 UBC           0 :                 memcpy(dst, "ANYKEY", 7);
     220               0 :                 res = 6;
     221                 :             }
     222                 :             else
     223 CBC          15 :                 res = print_key(keyid_buf, dst);
     224                 :         }
     225               2 :         else if (got_symenc_key)
     226                 :         {
     227 UBC           0 :             memcpy(dst, "SYMKEY", 7);
     228               0 :             res = 6;
     229                 :         }
     230                 :         else
     231 CBC           2 :             res = PXE_PGP_NO_USABLE_KEY;
     232                 :     }
     233                 : 
     234              17 :     return res;
     235                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a