LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgp-pubdec.c (source / functions) Coverage Total Hit UBC CBC
Current: 0e5ff9b9b45a657aea12440478dc002e9b01f138 vs 0123ce131fca454009439dfa3b2266d1d40737d7 Lines: 76.4 % 106 81 25 81
Current Date: 2026-03-14 14:10:32 -0400 Functions: 100.0 % 5 5 5
Baseline: lcov-20260315-024220-baseline Branches: 62.7 % 59 37 22 37
Baseline Date: 2026-03-14 15:27:56 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 6 6 6
(360..) days: 75.0 % 100 75 25 75
Function coverage date bins:
(360..) days: 100.0 % 5 5 5
Branch coverage date bins:
(30,360] days: 100.0 % 2 2 2
(360..) days: 61.4 % 57 35 22 35

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * pgp-pubdec.c
                                  3                 :                :  *    Decrypt public-key encrypted session 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-pubdec.c
                                 30                 :                :  */
                                 31                 :                : #include "postgres.h"
                                 32                 :                : 
                                 33                 :                : #include "pgp.h"
                                 34                 :                : #include "px.h"
                                 35                 :                : 
                                 36                 :                : /*
                                 37                 :                :  * padded msg = 02 || PS || 00 || M
                                 38                 :                :  * PS - pad bytes
                                 39                 :                :  * M - msg
                                 40                 :                :  */
                                 41                 :                : static uint8 *
 7553 bruce@momjian.us           42                 :CBC          14 : check_eme_pkcs1_v15(uint8 *data, int len)
                                 43                 :                : {
 7456                            44                 :             14 :     uint8      *data_end = data + len;
                                 45                 :             14 :     uint8      *p = data;
                                 46                 :             14 :     int         rnd = 0;
                                 47                 :                : 
 7553                            48         [ -  + ]:             14 :     if (len < 1 + 8 + 1)
 7553 bruce@momjian.us           49                 :UBC           0 :         return NULL;
                                 50                 :                : 
 7553 bruce@momjian.us           51         [ -  + ]:CBC          14 :     if (*p++ != 2)
 7553 bruce@momjian.us           52                 :UBC           0 :         return NULL;
                                 53                 :                : 
 7456 bruce@momjian.us           54   [ +  -  +  + ]:CBC        3127 :     while (p < data_end && *p)
                                 55                 :                :     {
 7553                            56                 :           3113 :         p++;
                                 57                 :           3113 :         rnd++;
                                 58                 :                :     }
                                 59                 :                : 
                                 60         [ -  + ]:             14 :     if (p == data_end)
 7553 bruce@momjian.us           61                 :UBC           0 :         return NULL;
 7553 bruce@momjian.us           62         [ -  + ]:CBC          14 :     if (*p != 0)
 7553 bruce@momjian.us           63                 :UBC           0 :         return NULL;
 7553 bruce@momjian.us           64         [ -  + ]:CBC          14 :     if (rnd < 8)
 7553 bruce@momjian.us           65                 :UBC           0 :         return NULL;
 7553 bruce@momjian.us           66                 :CBC          14 :     return p + 1;
                                 67                 :                : }
                                 68                 :                : 
                                 69                 :                : /*
                                 70                 :                :  * secret message: 1 byte algo, sesskey, 2 byte cksum
                                 71                 :                :  * ignore algo in cksum
                                 72                 :                :  */
                                 73                 :                : static int
                                 74                 :             14 : control_cksum(uint8 *msg, int msglen)
                                 75                 :                : {
                                 76                 :                :     int         i;
                                 77                 :                :     unsigned    my_cksum,
                                 78                 :                :                 got_cksum;
                                 79                 :                : 
                                 80         [ -  + ]:             14 :     if (msglen < 3)
 7519 bruce@momjian.us           81                 :UBC           0 :         return PXE_PGP_WRONG_KEY;
                                 82                 :                : 
 7553 bruce@momjian.us           83                 :CBC          14 :     my_cksum = 0;
                                 84         [ +  + ]:            274 :     for (i = 1; i < msglen - 2; i++)
                                 85                 :            260 :         my_cksum += msg[i];
                                 86                 :             14 :     my_cksum &= 0xFFFF;
 7456                            87                 :             14 :     got_cksum = ((unsigned) (msg[msglen - 2]) << 8) + msg[msglen - 1];
                                 88         [ -  + ]:             14 :     if (my_cksum != got_cksum)
                                 89                 :                :     {
 7553 bruce@momjian.us           90                 :UBC           0 :         px_debug("pubenc cksum failed");
 7519                            91                 :              0 :         return PXE_PGP_WRONG_KEY;
                                 92                 :                :     }
 7553 bruce@momjian.us           93                 :CBC          14 :     return 0;
                                 94                 :                : }
                                 95                 :                : 
                                 96                 :                : static int
 6121                            97                 :              9 : decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
                                 98                 :                : {
                                 99                 :                :     int         res;
 7456                           100                 :              9 :     PGP_MPI    *c1 = NULL;
                                101                 :              9 :     PGP_MPI    *c2 = NULL;
                                102                 :                : 
 7519                           103         [ -  + ]:              9 :     if (pk->algo != PGP_PUB_ELG_ENCRYPT)
 7519 bruce@momjian.us          104                 :UBC           0 :         return PXE_PGP_WRONG_KEY;
                                105                 :                : 
                                106                 :                :     /* read elgamal encrypted data */
 7519 bruce@momjian.us          107                 :CBC           9 :     res = pgp_mpi_read(pkt, &c1);
                                108         [ -  + ]:              9 :     if (res < 0)
 7519 bruce@momjian.us          109                 :UBC           0 :         goto out;
 7519 bruce@momjian.us          110                 :CBC           9 :     res = pgp_mpi_read(pkt, &c2);
                                111         [ -  + ]:              9 :     if (res < 0)
 7519 bruce@momjian.us          112                 :UBC           0 :         goto out;
                                113                 :                : 
                                114                 :                :     /* decrypt */
 7519 bruce@momjian.us          115                 :CBC           9 :     res = pgp_elgamal_decrypt(pk, c1, c2, m_p);
                                116                 :                : 
                                117                 :              9 : out:
                                118                 :              9 :     pgp_mpi_free(c1);
                                119                 :              9 :     pgp_mpi_free(c2);
                                120                 :              9 :     return res;
                                121                 :                : }
                                122                 :                : 
                                123                 :                : static int
 6121                           124                 :              5 : decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
                                125                 :                : {
                                126                 :                :     int         res;
                                127                 :                :     PGP_MPI    *c;
                                128                 :                : 
 7519                           129         [ +  + ]:              5 :     if (pk->algo != PGP_PUB_RSA_ENCRYPT
 7456                           130         [ -  + ]:              4 :         && pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
 7519 bruce@momjian.us          131                 :UBC           0 :         return PXE_PGP_WRONG_KEY;
                                132                 :                : 
                                133                 :                :     /* read rsa encrypted data */
 7519 bruce@momjian.us          134                 :CBC           5 :     res = pgp_mpi_read(pkt, &c);
                                135         [ -  + ]:              5 :     if (res < 0)
 7519 bruce@momjian.us          136                 :UBC           0 :         return res;
                                137                 :                : 
                                138                 :                :     /* decrypt */
 7519 bruce@momjian.us          139                 :CBC           5 :     res = pgp_rsa_decrypt(pk, c, m_p);
                                140                 :                : 
                                141                 :              5 :     pgp_mpi_free(c);
                                142                 :              5 :     return res;
                                143                 :                : }
                                144                 :                : 
                                145                 :                : /* key id is missing - user is expected to try all keys */
                                146                 :                : static const uint8
                                147                 :                :             any_key[] = {0, 0, 0, 0, 0, 0, 0, 0};
                                148                 :                : 
                                149                 :                : int
 6121                           150                 :             15 : pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt)
                                151                 :                : {
                                152                 :                :     int         ver;
                                153                 :                :     int         algo;
                                154                 :                :     int         res;
                                155                 :                :     uint8       key_id[8];
                                156                 :                :     PGP_PubKey *pk;
                                157                 :                :     uint8      *msg;
                                158                 :                :     int         msglen;
                                159                 :                :     PGP_MPI    *m;
                                160                 :                :     unsigned    sess_key_len;
                                161                 :                : 
 7553                           162                 :             15 :     pk = ctx->pub_key;
 7456                           163         [ -  + ]:             15 :     if (pk == NULL)
                                164                 :                :     {
 7553 bruce@momjian.us          165                 :UBC           0 :         px_debug("no pubkey?");
                                166                 :              0 :         return PXE_BUG;
                                167                 :                :     }
                                168                 :                : 
 7553 bruce@momjian.us          169         [ -  + ]:CBC          15 :     GETBYTE(pkt, ver);
 7456                           170         [ -  + ]:             15 :     if (ver != 3)
                                171                 :                :     {
 7553 bruce@momjian.us          172                 :UBC           0 :         px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
                                173                 :              0 :         return PXE_PGP_CORRUPT_DATA;
                                174                 :                :     }
                                175                 :                : 
                                176                 :                :     /*
                                177                 :                :      * check if keyid's match - user-friendly msg
                                178                 :                :      */
 7553 bruce@momjian.us          179                 :CBC          15 :     res = pullf_read_fixed(pkt, 8, key_id);
                                180         [ -  + ]:             15 :     if (res < 0)
 7553 bruce@momjian.us          181                 :UBC           0 :         return res;
 7553 bruce@momjian.us          182         [ +  + ]:CBC          15 :     if (memcmp(key_id, any_key, 8) != 0
 7456                           183         [ +  + ]:             14 :         && memcmp(key_id, pk->key_id, 8) != 0)
                                184                 :                :     {
 7553                           185                 :              1 :         px_debug("key_id's does not match");
 7519                           186                 :              1 :         return PXE_PGP_WRONG_KEY;
                                187                 :                :     }
                                188                 :                : 
                                189                 :                :     /*
                                190                 :                :      * Decrypt
                                191                 :                :      */
 7553                           192         [ -  + ]:             14 :     GETBYTE(pkt, algo);
 7519                           193      [ +  +  - ]:             14 :     switch (algo)
                                194                 :                :     {
                                195                 :              9 :         case PGP_PUB_ELG_ENCRYPT:
                                196                 :              9 :             res = decrypt_elgamal(pk, pkt, &m);
                                197                 :              9 :             break;
                                198                 :              5 :         case PGP_PUB_RSA_ENCRYPT:
                                199                 :                :         case PGP_PUB_RSA_ENCRYPT_SIGN:
                                200                 :              5 :             res = decrypt_rsa(pk, pkt, &m);
                                201                 :              5 :             break;
 7519 bruce@momjian.us          202                 :UBC           0 :         default:
                                203                 :              0 :             res = PXE_PGP_UNKNOWN_PUBALGO;
                                204                 :                :     }
 7553 bruce@momjian.us          205         [ -  + ]:CBC          14 :     if (res < 0)
 7553 bruce@momjian.us          206                 :UBC           0 :         return res;
                                207                 :                : 
                                208                 :                :     /*
                                209                 :                :      * extract message
                                210                 :                :      */
 7553 bruce@momjian.us          211                 :CBC          14 :     msg = check_eme_pkcs1_v15(m->data, m->bytes);
 7456                           212         [ -  + ]:             14 :     if (msg == NULL)
                                213                 :                :     {
 7553 bruce@momjian.us          214                 :UBC           0 :         px_debug("check_eme_pkcs1_v15 failed");
 7519                           215                 :              0 :         res = PXE_PGP_WRONG_KEY;
                                216                 :              0 :         goto out;
                                217                 :                :     }
 7553 bruce@momjian.us          218                 :CBC          14 :     msglen = m->bytes - (msg - m->data);
                                219                 :                : 
                                220                 :             14 :     res = control_cksum(msg, msglen);
                                221         [ -  + ]:             14 :     if (res < 0)
 7519 bruce@momjian.us          222                 :UBC           0 :         goto out;
                                223                 :                : 
   34 michael@paquier.xyz       224                 :CBC          14 :     sess_key_len = msglen - 3;
                                225         [ +  + ]:             14 :     if (sess_key_len > PGP_MAX_KEY)
                                226                 :                :     {
                                227                 :              1 :         px_debug("incorrect session key length=%u", sess_key_len);
                                228                 :              1 :         res = PXE_PGP_KEY_TOO_BIG;
                                229                 :              1 :         goto out;
                                230                 :                :     }
                                231                 :                : 
                                232                 :                :     /*
                                233                 :                :      * got sesskey
                                234                 :                :      */
 7553 bruce@momjian.us          235                 :             13 :     ctx->cipher_algo = *msg;
   34 michael@paquier.xyz       236                 :             13 :     ctx->sess_key_len = sess_key_len;
 7553 bruce@momjian.us          237                 :             13 :     memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len);
                                238                 :                : 
 7519                           239                 :             14 : out:
                                240                 :             14 :     pgp_mpi_free(m);
                                241         [ +  + ]:             14 :     if (res < 0)
                                242                 :              1 :         return res;
 7553                           243                 :             13 :     return pgp_expect_packet_end(pkt);
                                244                 :                : }
        

Generated by: LCOV version 2.4-beta