LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgp-pubdec.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 74.3 % 101 75 26 75
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 5 5 5
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 74.3 % 101 75 26 75
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 5 5 5

 Age         Owner                  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 *
 6482 bruce                      42 CBC          13 : check_eme_pkcs1_v15(uint8 *data, int len)
                                 43                 : {
 6385                            44              13 :     uint8      *data_end = data + len;
                                 45              13 :     uint8      *p = data;
                                 46              13 :     int         rnd = 0;
                                 47                 : 
 6482                            48              13 :     if (len < 1 + 8 + 1)
 6482 bruce                      49 UBC           0 :         return NULL;
                                 50                 : 
 6482 bruce                      51 CBC          13 :     if (*p++ != 2)
 6482 bruce                      52 UBC           0 :         return NULL;
                                 53                 : 
 6385 bruce                      54 CBC        2911 :     while (p < data_end && *p)
                                 55                 :     {
 6482                            56            2898 :         p++;
                                 57            2898 :         rnd++;
                                 58                 :     }
                                 59                 : 
                                 60              13 :     if (p == data_end)
 6482 bruce                      61 UBC           0 :         return NULL;
 6482 bruce                      62 CBC          13 :     if (*p != 0)
 6482 bruce                      63 UBC           0 :         return NULL;
 6482 bruce                      64 CBC          13 :     if (rnd < 8)
 6482 bruce                      65 UBC           0 :         return NULL;
 6482 bruce                      66 CBC          13 :     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              13 : control_cksum(uint8 *msg, int msglen)
                                 75                 : {
                                 76                 :     int         i;
                                 77                 :     unsigned    my_cksum,
                                 78                 :                 got_cksum;
                                 79                 : 
                                 80              13 :     if (msglen < 3)
 6448 bruce                      81 UBC           0 :         return PXE_PGP_WRONG_KEY;
                                 82                 : 
 6482 bruce                      83 CBC          13 :     my_cksum = 0;
                                 84             237 :     for (i = 1; i < msglen - 2; i++)
                                 85             224 :         my_cksum += msg[i];
                                 86              13 :     my_cksum &= 0xFFFF;
 6385                            87              13 :     got_cksum = ((unsigned) (msg[msglen - 2]) << 8) + msg[msglen - 1];
                                 88              13 :     if (my_cksum != got_cksum)
                                 89                 :     {
 6482 bruce                      90 UBC           0 :         px_debug("pubenc cksum failed");
 6448                            91               0 :         return PXE_PGP_WRONG_KEY;
                                 92                 :     }
 6482 bruce                      93 CBC          13 :     return 0;
                                 94                 : }
                                 95                 : 
                                 96                 : static int
 5050                            97               9 : decrypt_elgamal(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
                                 98                 : {
                                 99                 :     int         res;
 6385                           100               9 :     PGP_MPI    *c1 = NULL;
                                101               9 :     PGP_MPI    *c2 = NULL;
                                102                 : 
 6448                           103               9 :     if (pk->algo != PGP_PUB_ELG_ENCRYPT)
 6448 bruce                     104 UBC           0 :         return PXE_PGP_WRONG_KEY;
                                105                 : 
                                106                 :     /* read elgamal encrypted data */
 6448 bruce                     107 CBC           9 :     res = pgp_mpi_read(pkt, &c1);
                                108               9 :     if (res < 0)
 6448 bruce                     109 UBC           0 :         goto out;
 6448 bruce                     110 CBC           9 :     res = pgp_mpi_read(pkt, &c2);
                                111               9 :     if (res < 0)
 6448 bruce                     112 UBC           0 :         goto out;
                                113                 : 
                                114                 :     /* decrypt */
 6448 bruce                     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
 5050                           124               4 : decrypt_rsa(PGP_PubKey *pk, PullFilter *pkt, PGP_MPI **m_p)
                                125                 : {
                                126                 :     int         res;
                                127                 :     PGP_MPI    *c;
                                128                 : 
 6448                           129               4 :     if (pk->algo != PGP_PUB_RSA_ENCRYPT
 6385                           130               4 :         && pk->algo != PGP_PUB_RSA_ENCRYPT_SIGN)
 6448 bruce                     131 UBC           0 :         return PXE_PGP_WRONG_KEY;
                                132                 : 
                                133                 :     /* read rsa encrypted data */
 6448 bruce                     134 CBC           4 :     res = pgp_mpi_read(pkt, &c);
                                135               4 :     if (res < 0)
 6448 bruce                     136 UBC           0 :         return res;
                                137                 : 
                                138                 :     /* decrypt */
 6448 bruce                     139 CBC           4 :     res = pgp_rsa_decrypt(pk, c, m_p);
                                140                 : 
                                141               4 :     pgp_mpi_free(c);
                                142               4 :     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
 5050                           150              14 : 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                 : 
 6482                           161              14 :     pk = ctx->pub_key;
 6385                           162              14 :     if (pk == NULL)
                                163                 :     {
 6482 bruce                     164 UBC           0 :         px_debug("no pubkey?");
                                165               0 :         return PXE_BUG;
                                166                 :     }
                                167                 : 
 6482 bruce                     168 CBC          14 :     GETBYTE(pkt, ver);
 6385                           169              14 :     if (ver != 3)
                                170                 :     {
 6482 bruce                     171 UBC           0 :         px_debug("unknown pubenc_sesskey pkt ver=%d", ver);
                                172               0 :         return PXE_PGP_CORRUPT_DATA;
                                173                 :     }
                                174                 : 
                                175                 :     /*
                                176                 :      * check if keyid's match - user-friendly msg
                                177                 :      */
 6482 bruce                     178 CBC          14 :     res = pullf_read_fixed(pkt, 8, key_id);
                                179              14 :     if (res < 0)
 6482 bruce                     180 UBC           0 :         return res;
 6482 bruce                     181 CBC          14 :     if (memcmp(key_id, any_key, 8) != 0
 6385                           182              14 :         && memcmp(key_id, pk->key_id, 8) != 0)
                                183                 :     {
 6482                           184               1 :         px_debug("key_id's does not match");
 6448                           185               1 :         return PXE_PGP_WRONG_KEY;
                                186                 :     }
                                187                 : 
                                188                 :     /*
                                189                 :      * Decrypt
                                190                 :      */
 6482                           191              13 :     GETBYTE(pkt, algo);
 6448                           192              13 :     switch (algo)
                                193                 :     {
                                194               9 :         case PGP_PUB_ELG_ENCRYPT:
                                195               9 :             res = decrypt_elgamal(pk, pkt, &m);
                                196               9 :             break;
                                197               4 :         case PGP_PUB_RSA_ENCRYPT:
                                198                 :         case PGP_PUB_RSA_ENCRYPT_SIGN:
                                199               4 :             res = decrypt_rsa(pk, pkt, &m);
                                200               4 :             break;
 6448 bruce                     201 UBC           0 :         default:
                                202               0 :             res = PXE_PGP_UNKNOWN_PUBALGO;
                                203                 :     }
 6482 bruce                     204 CBC          13 :     if (res < 0)
 6482 bruce                     205 UBC           0 :         return res;
                                206                 : 
                                207                 :     /*
                                208                 :      * extract message
                                209                 :      */
 6482 bruce                     210 CBC          13 :     msg = check_eme_pkcs1_v15(m->data, m->bytes);
 6385                           211              13 :     if (msg == NULL)
                                212                 :     {
 6482 bruce                     213 UBC           0 :         px_debug("check_eme_pkcs1_v15 failed");
 6448                           214               0 :         res = PXE_PGP_WRONG_KEY;
                                215               0 :         goto out;
                                216                 :     }
 6482 bruce                     217 CBC          13 :     msglen = m->bytes - (msg - m->data);
                                218                 : 
                                219              13 :     res = control_cksum(msg, msglen);
                                220              13 :     if (res < 0)
 6448 bruce                     221 UBC           0 :         goto out;
                                222                 : 
                                223                 :     /*
                                224                 :      * got sesskey
                                225                 :      */
 6482 bruce                     226 CBC          13 :     ctx->cipher_algo = *msg;
                                227              13 :     ctx->sess_key_len = msglen - 3;
                                228              13 :     memcpy(ctx->sess_key, msg + 1, ctx->sess_key_len);
                                229                 : 
 6448                           230              13 : out:
                                231              13 :     pgp_mpi_free(m);
                                232              13 :     if (res < 0)
 6448 bruce                     233 UBC           0 :         return res;
 6482 bruce                     234 CBC          13 :     return pgp_expect_packet_end(pkt);
                                235                 : }
        

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