LCOV - code coverage report
Current view: top level - contrib/pgcrypto - pgp-pubenc.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 123 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-pubenc.c
       3              :  *        Encrypt session key with public 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-pubenc.c
      30              :  */
      31              : #include "postgres.h"
      32              : 
      33              : #include "pgp.h"
      34              : #include "px.h"
      35              : 
      36              : /*
      37              :  * padded msg: 02 || non-zero pad bytes || 00 || msg
      38              :  */
      39              : static int
      40            0 : pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p)
      41              : {
      42            0 :         uint8      *buf,
      43              :                            *p;
      44            0 :         int                     pad_len = res_len - 2 - data_len;
      45              : 
      46            0 :         if (pad_len < 8)
      47            0 :                 return PXE_BUG;
      48              : 
      49            0 :         buf = palloc(res_len);
      50            0 :         buf[0] = 0x02;
      51              : 
      52            0 :         if (!pg_strong_random(buf + 1, pad_len))
      53              :         {
      54            0 :                 pfree(buf);
      55            0 :                 return PXE_NO_RANDOM;
      56              :         }
      57              : 
      58              :         /* pad must not contain zero bytes */
      59            0 :         p = buf + 1;
      60            0 :         while (p < buf + 1 + pad_len)
      61              :         {
      62            0 :                 if (*p == 0)
      63              :                 {
      64            0 :                         if (!pg_strong_random(p, 1))
      65              :                         {
      66            0 :                                 px_memset(buf, 0, res_len);
      67            0 :                                 pfree(buf);
      68            0 :                                 return PXE_NO_RANDOM;
      69              :                         }
      70            0 :                 }
      71            0 :                 if (*p != 0)
      72            0 :                         p++;
      73              :         }
      74              : 
      75            0 :         buf[pad_len + 1] = 0;
      76            0 :         memcpy(buf + pad_len + 2, data, data_len);
      77            0 :         *res_p = buf;
      78              : 
      79            0 :         return 0;
      80            0 : }
      81              : 
      82              : static int
      83            0 : create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes)
      84              : {
      85            0 :         uint8      *secmsg;
      86            0 :         int                     res,
      87              :                                 i;
      88            0 :         unsigned        cksum = 0;
      89            0 :         int                     klen = ctx->sess_key_len;
      90            0 :         uint8      *padded = NULL;
      91            0 :         PGP_MPI    *m = NULL;
      92              : 
      93              :         /* calc checksum */
      94            0 :         for (i = 0; i < klen; i++)
      95            0 :                 cksum += ctx->sess_key[i];
      96              : 
      97              :         /*
      98              :          * create "secret message"
      99              :          */
     100            0 :         secmsg = palloc(klen + 3);
     101            0 :         secmsg[0] = ctx->cipher_algo;
     102            0 :         memcpy(secmsg + 1, ctx->sess_key, klen);
     103            0 :         secmsg[klen + 1] = (cksum >> 8) & 0xFF;
     104            0 :         secmsg[klen + 2] = cksum & 0xFF;
     105              : 
     106              :         /*
     107              :          * now create a large integer of it
     108              :          */
     109            0 :         res = pad_eme_pkcs1_v15(secmsg, klen + 3, full_bytes, &padded);
     110            0 :         if (res >= 0)
     111              :         {
     112              :                 /* first byte will be 0x02 */
     113            0 :                 int                     full_bits = full_bytes * 8 - 6;
     114              : 
     115            0 :                 res = pgp_mpi_create(padded, full_bits, &m);
     116            0 :         }
     117              : 
     118            0 :         if (padded)
     119              :         {
     120            0 :                 px_memset(padded, 0, full_bytes);
     121            0 :                 pfree(padded);
     122            0 :         }
     123            0 :         px_memset(secmsg, 0, klen + 3);
     124            0 :         pfree(secmsg);
     125              : 
     126            0 :         if (res >= 0)
     127            0 :                 *msg_p = m;
     128              : 
     129            0 :         return res;
     130            0 : }
     131              : 
     132              : static int
     133            0 : encrypt_and_write_elgamal(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
     134              : {
     135            0 :         int                     res;
     136            0 :         PGP_MPI    *m = NULL,
     137            0 :                            *c1 = NULL,
     138            0 :                            *c2 = NULL;
     139              : 
     140              :         /* create padded msg */
     141            0 :         res = create_secmsg(ctx, &m, pk->pub.elg.p->bytes - 1);
     142            0 :         if (res < 0)
     143            0 :                 goto err;
     144              : 
     145              :         /* encrypt it */
     146            0 :         res = pgp_elgamal_encrypt(pk, m, &c1, &c2);
     147            0 :         if (res < 0)
     148            0 :                 goto err;
     149              : 
     150              :         /* write out */
     151            0 :         res = pgp_mpi_write(pkt, c1);
     152            0 :         if (res < 0)
     153            0 :                 goto err;
     154            0 :         res = pgp_mpi_write(pkt, c2);
     155              : 
     156              : err:
     157            0 :         pgp_mpi_free(m);
     158            0 :         pgp_mpi_free(c1);
     159            0 :         pgp_mpi_free(c2);
     160            0 :         return res;
     161            0 : }
     162              : 
     163              : static int
     164            0 : encrypt_and_write_rsa(PGP_Context *ctx, PGP_PubKey *pk, PushFilter *pkt)
     165              : {
     166            0 :         int                     res;
     167            0 :         PGP_MPI    *m = NULL,
     168            0 :                            *c = NULL;
     169              : 
     170              :         /* create padded msg */
     171            0 :         res = create_secmsg(ctx, &m, pk->pub.rsa.n->bytes - 1);
     172            0 :         if (res < 0)
     173            0 :                 goto err;
     174              : 
     175              :         /* encrypt it */
     176            0 :         res = pgp_rsa_encrypt(pk, m, &c);
     177            0 :         if (res < 0)
     178            0 :                 goto err;
     179              : 
     180              :         /* write out */
     181            0 :         res = pgp_mpi_write(pkt, c);
     182              : 
     183              : err:
     184            0 :         pgp_mpi_free(m);
     185            0 :         pgp_mpi_free(c);
     186            0 :         return res;
     187            0 : }
     188              : 
     189              : int
     190            0 : pgp_write_pubenc_sesskey(PGP_Context *ctx, PushFilter *dst)
     191              : {
     192            0 :         int                     res;
     193            0 :         PGP_PubKey *pk = ctx->pub_key;
     194            0 :         uint8           ver = 3;
     195            0 :         PushFilter *pkt = NULL;
     196            0 :         uint8           algo;
     197              : 
     198            0 :         if (pk == NULL)
     199              :         {
     200            0 :                 px_debug("no pubkey?\n");
     201            0 :                 return PXE_BUG;
     202              :         }
     203              : 
     204            0 :         algo = pk->algo;
     205              : 
     206              :         /*
     207              :          * now write packet
     208              :          */
     209            0 :         res = pgp_create_pkt_writer(dst, PGP_PKT_PUBENCRYPTED_SESSKEY, &pkt);
     210            0 :         if (res < 0)
     211            0 :                 goto err;
     212            0 :         res = pushf_write(pkt, &ver, 1);
     213            0 :         if (res < 0)
     214            0 :                 goto err;
     215            0 :         res = pushf_write(pkt, pk->key_id, 8);
     216            0 :         if (res < 0)
     217            0 :                 goto err;
     218            0 :         res = pushf_write(pkt, &algo, 1);
     219            0 :         if (res < 0)
     220            0 :                 goto err;
     221              : 
     222            0 :         switch (algo)
     223              :         {
     224              :                 case PGP_PUB_ELG_ENCRYPT:
     225            0 :                         res = encrypt_and_write_elgamal(ctx, pk, pkt);
     226            0 :                         break;
     227              :                 case PGP_PUB_RSA_ENCRYPT:
     228              :                 case PGP_PUB_RSA_ENCRYPT_SIGN:
     229            0 :                         res = encrypt_and_write_rsa(ctx, pk, pkt);
     230            0 :                         break;
     231              :         }
     232            0 :         if (res < 0)
     233            0 :                 goto err;
     234              : 
     235              :         /*
     236              :          * done, signal packet end
     237              :          */
     238            0 :         res = pushf_flush(pkt);
     239              : err:
     240            0 :         if (pkt)
     241            0 :                 pushf_free(pkt);
     242              : 
     243            0 :         return res;
     244            0 : }
        

Generated by: LCOV version 2.3.2-1