LCOV - code coverage report
Current view: top level - contrib/pgcrypto - pgp-pubdec.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 115 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 5 0
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.3.2-1