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

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  * pgp-decrypt.c
                                  3                 :  *    OpenPGP decrypt.
                                  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-decrypt.c
                                 30                 :  */
                                 31                 : 
                                 32                 : #include "postgres.h"
                                 33                 : 
                                 34                 : #include "mbuf.h"
                                 35                 : #include "pgp.h"
                                 36                 : #include "px.h"
                                 37                 : 
                                 38                 : #define NO_CTX_SIZE     0
                                 39                 : #define ALLOW_CTX_SIZE  1
                                 40                 : #define NO_COMPR        0
                                 41                 : #define ALLOW_COMPR     1
                                 42                 : #define NO_MDC          0
                                 43                 : #define NEED_MDC        1
                                 44                 : 
                                 45                 : #define PKT_NORMAL 1
                                 46                 : #define PKT_STREAM 2
                                 47                 : #define PKT_CONTEXT 3
                                 48                 : 
                                 49                 : #define MAX_CHUNK (16*1024*1024)
                                 50                 : 
                                 51                 : static int
 5050 bruce                      52 CBC         268 : parse_new_len(PullFilter *src, int *len_p)
                                 53                 : {
                                 54                 :     uint8       b;
                                 55                 :     int         len;
 6482                            56             268 :     int         pkttype = PKT_NORMAL;
                                 57                 : 
                                 58             268 :     GETBYTE(src, b);
                                 59             268 :     if (b <= 191)
                                 60             244 :         len = b;
                                 61              24 :     else if (b >= 192 && b <= 223)
                                 62                 :     {
                                 63               8 :         len = ((unsigned) (b) - 192) << 8;
                                 64               8 :         GETBYTE(src, b);
                                 65               8 :         len += 192 + b;
                                 66                 :     }
                                 67              16 :     else if (b == 255)
                                 68                 :     {
                                 69               1 :         GETBYTE(src, b);
                                 70               1 :         len = b;
                                 71               1 :         GETBYTE(src, b);
                                 72               1 :         len = (len << 8) | b;
                                 73               1 :         GETBYTE(src, b);
                                 74               1 :         len = (len << 8) | b;
                                 75               1 :         GETBYTE(src, b);
                                 76               1 :         len = (len << 8) | b;
                                 77                 :     }
                                 78                 :     else
                                 79                 :     {
                                 80              15 :         len = 1 << (b & 0x1F);
                                 81              15 :         pkttype = PKT_STREAM;
                                 82                 :     }
                                 83                 : 
                                 84             268 :     if (len < 0 || len > MAX_CHUNK)
                                 85                 :     {
 6482 bruce                      86 UBC           0 :         px_debug("parse_new_len: weird length");
                                 87               0 :         return PXE_PGP_CORRUPT_DATA;
                                 88                 :     }
                                 89                 : 
 6482 bruce                      90 CBC         268 :     *len_p = len;
                                 91             268 :     return pkttype;
                                 92                 : }
                                 93                 : 
                                 94                 : static int
 5050                            95             213 : parse_old_len(PullFilter *src, int *len_p, int lentype)
                                 96                 : {
                                 97                 :     uint8       b;
                                 98                 :     int         len;
                                 99                 : 
 6482                           100             213 :     GETBYTE(src, b);
                                101             213 :     len = b;
                                102                 : 
                                103             213 :     if (lentype == 1)
                                104                 :     {
                                105             102 :         GETBYTE(src, b);
                                106             102 :         len = (len << 8) | b;
                                107                 :     }
                                108             111 :     else if (lentype == 2)
                                109                 :     {
 6482 bruce                     110 UBC           0 :         GETBYTE(src, b);
                                111               0 :         len = (len << 8) | b;
                                112               0 :         GETBYTE(src, b);
                                113               0 :         len = (len << 8) | b;
                                114               0 :         GETBYTE(src, b);
                                115               0 :         len = (len << 8) | b;
                                116                 :     }
                                117                 : 
 6482 bruce                     118 CBC         213 :     if (len < 0 || len > MAX_CHUNK)
                                119                 :     {
 6482 bruce                     120 UBC           0 :         px_debug("parse_old_len: weird length");
                                121               0 :         return PXE_PGP_CORRUPT_DATA;
                                122                 :     }
 6482 bruce                     123 CBC         213 :     *len_p = len;
                                124             213 :     return PKT_NORMAL;
                                125                 : }
                                126                 : 
                                127                 : /* returns pkttype or 0 on eof */
                                128                 : int
 5050                           129             645 : pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
                                130                 : {
                                131                 :     int         lentype;
                                132                 :     int         res;
                                133                 :     uint8      *p;
                                134                 : 
                                135                 :     /* EOF is normal here, thus we don't use GETBYTE */
 6482                           136             645 :     res = pullf_read(src, 1, &p);
                                137             645 :     if (res < 0)
 6482 bruce                     138 UBC           0 :         return res;
 6482 bruce                     139 CBC         645 :     if (res == 0)
                                140             172 :         return 0;
                                141                 : 
                                142             473 :     if ((*p & 0x80) == 0)
                                143                 :     {
                                144               2 :         px_debug("pgp_parse_pkt_hdr: not pkt hdr");
                                145               2 :         return PXE_PGP_CORRUPT_DATA;
                                146                 :     }
                                147                 : 
                                148             471 :     if (*p & 0x40)
                                149                 :     {
                                150             255 :         *tag = *p & 0x3f;
                                151             255 :         res = parse_new_len(src, len_p);
                                152                 :     }
                                153                 :     else
                                154                 :     {
                                155             216 :         lentype = *p & 3;
                                156             216 :         *tag = (*p >> 2) & 0x0F;
                                157             216 :         if (lentype == 3)
                                158               3 :             res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
                                159                 :         else
                                160             213 :             res = parse_old_len(src, len_p, lentype);
                                161                 :     }
                                162             471 :     return res;
                                163                 : }
                                164                 : 
                                165                 : /*
                                166                 :  * Packet reader
                                167                 :  */
                                168                 : struct PktData
                                169                 : {
                                170                 :     int         type;
                                171                 :     int         len;
                                172                 : };
                                173                 : 
                                174                 : static int
 5050                           175            2542 : pktreader_pull(void *priv, PullFilter *src, int len,
                                176                 :                uint8 **data_p, uint8 *buf, int buflen)
                                177                 : {
                                178                 :     int         res;
 6482                           179            2542 :     struct PktData *pkt = priv;
                                180                 : 
                                181                 :     /* PKT_CONTEXT means: whatever there is */
                                182            2542 :     if (pkt->type == PKT_CONTEXT)
 6482 bruce                     183 UBC           0 :         return pullf_read(src, len, data_p);
                                184                 : 
 3071 tgl                       185 CBC        2555 :     while (pkt->len == 0)
                                186                 :     {
                                187                 :         /* this was last chunk in stream */
 6482 bruce                     188             400 :         if (pkt->type == PKT_NORMAL)
                                189             387 :             return 0;
                                190                 : 
                                191                 :         /* next chunk in stream */
                                192              13 :         res = parse_new_len(src, &pkt->len);
                                193              13 :         if (res < 0)
 6482 bruce                     194 UBC           0 :             return res;
 6482 bruce                     195 CBC          13 :         pkt->type = res;
                                196                 :     }
                                197                 : 
                                198            2155 :     if (len > pkt->len)
                                199             263 :         len = pkt->len;
                                200                 : 
                                201            2155 :     res = pullf_read(src, len, data_p);
                                202            2155 :     if (res > 0)
                                203            2155 :         pkt->len -= res;
                                204                 : 
                                205            2155 :     return res;
                                206                 : }
                                207                 : 
                                208                 : static void
                                209             468 : pktreader_free(void *priv)
                                210                 : {
                                211             468 :     struct PktData *pkt = priv;
                                212                 : 
 3279                           213             468 :     px_memset(pkt, 0, sizeof(*pkt));
  926 michael                   214             468 :     pfree(pkt);
 6482 bruce                     215             468 : }
                                216                 : 
                                217                 : static struct PullFilterOps pktreader_filter = {
                                218                 :     NULL, pktreader_pull, pktreader_free
                                219                 : };
                                220                 : 
                                221                 : /* needs helper function to pass several parameters */
                                222                 : int
 5050                           223             468 : pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
                                224                 :                       int pkttype, PGP_Context *ctx)
                                225                 : {
                                226                 :     int         res;
  926 michael                   227             468 :     struct PktData *pkt = palloc(sizeof(*pkt));
                                228                 : 
 6482 bruce                     229             468 :     pkt->type = pkttype;
                                230             468 :     pkt->len = len;
                                231             468 :     res = pullf_create(pf_p, &pktreader_filter, pkt, src);
                                232             468 :     if (res < 0)
  926 michael                   233 UBC           0 :         pfree(pkt);
 6482 bruce                     234 CBC         468 :     return res;
                                235                 : }
                                236                 : 
                                237                 : /*
                                238                 :  * Prefix check filter
                                239                 :  * https://tools.ietf.org/html/rfc4880#section-5.7
                                240                 :  * https://tools.ietf.org/html/rfc4880#section-5.13
                                241                 :  */
                                242                 : 
                                243                 : static int
 5050                           244              72 : prefix_init(void **priv_p, void *arg, PullFilter *src)
                                245                 : {
 6482                           246              72 :     PGP_Context *ctx = arg;
                                247                 :     int         len;
                                248                 :     int         res;
                                249                 :     uint8      *buf;
                                250                 :     uint8       tmpbuf[PGP_MAX_BLOCK + 2];
                                251                 : 
                                252              72 :     len = pgp_get_cipher_block_size(ctx->cipher_algo);
                                253              72 :     if (len > sizeof(tmpbuf))
 6482 bruce                     254 UBC           0 :         return PXE_BUG;
                                255                 : 
 6482 bruce                     256 CBC          72 :     res = pullf_read_max(src, len + 2, &buf, tmpbuf);
                                257              72 :     if (res < 0)
 6482 bruce                     258 UBC           0 :         return res;
 6482 bruce                     259 CBC          72 :     if (res != len + 2)
                                260                 :     {
 6482 bruce                     261 UBC           0 :         px_debug("prefix_init: short read");
 3279                           262               0 :         px_memset(tmpbuf, 0, sizeof(tmpbuf));
 6482                           263               0 :         return PXE_PGP_CORRUPT_DATA;
                                264                 :     }
                                265                 : 
 6482 bruce                     266 CBC          72 :     if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
                                267                 :     {
                                268               4 :         px_debug("prefix_init: corrupt prefix");
                                269                 :         /* report error in pgp_decrypt() */
                                270               4 :         ctx->corrupt_prefix = 1;
                                271                 :     }
 3279                           272              72 :     px_memset(tmpbuf, 0, sizeof(tmpbuf));
 6482                           273              72 :     return 0;
                                274                 : }
                                275                 : 
                                276                 : static struct PullFilterOps prefix_filter = {
                                277                 :     prefix_init, NULL, NULL
                                278                 : };
                                279                 : 
                                280                 : 
                                281                 : /*
                                282                 :  * Decrypt filter
                                283                 :  */
                                284                 : 
                                285                 : static int
 5050                           286              76 : decrypt_init(void **priv_p, void *arg, PullFilter *src)
                                287                 : {
 6385                           288              76 :     PGP_CFB    *cfb = arg;
                                289                 : 
 6482                           290              76 :     *priv_p = cfb;
                                291                 : 
                                292                 :     /* we need to write somewhere, so ask for a buffer */
                                293              76 :     return 4096;
                                294                 : }
                                295                 : 
                                296                 : static int
 5050                           297             804 : decrypt_read(void *priv, PullFilter *src, int len,
                                298                 :              uint8 **data_p, uint8 *buf, int buflen)
                                299                 : {
 6385                           300             804 :     PGP_CFB    *cfb = priv;
                                301                 :     uint8      *tmp;
                                302                 :     int         res;
                                303                 : 
 6482                           304             804 :     res = pullf_read(src, len, &tmp);
 6385                           305             804 :     if (res > 0)
                                306                 :     {
 6482                           307             730 :         pgp_cfb_decrypt(cfb, tmp, res, buf);
                                308             730 :         *data_p = buf;
                                309                 :     }
                                310             804 :     return res;
                                311                 : }
                                312                 : 
                                313                 : struct PullFilterOps pgp_decrypt_filter = {
                                314                 :     decrypt_init, decrypt_read, NULL
                                315                 : };
                                316                 : 
                                317                 : 
                                318                 : /*
                                319                 :  * MDC hasher filter
                                320                 :  */
                                321                 : 
                                322                 : static int
 5050                           323              70 : mdc_init(void **priv_p, void *arg, PullFilter *src)
                                324                 : {
 6482                           325              70 :     PGP_Context *ctx = arg;
                                326                 : 
                                327              70 :     *priv_p = ctx;
                                328              70 :     return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
                                329                 : }
                                330                 : 
                                331                 : static void
 6385                           332              70 : mdc_free(void *priv)
                                333                 : {
 6482                           334              70 :     PGP_Context *ctx = priv;
                                335                 : 
                                336              70 :     if (ctx->use_mdcbuf_filter)
                                337               3 :         return;
                                338              67 :     px_md_free(ctx->mdc_ctx);
                                339              67 :     ctx->mdc_ctx = NULL;
                                340                 : }
                                341                 : 
                                342                 : static int
 2991 tgl                       343              64 : mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
                                344                 : {
                                345                 :     int         res;
                                346                 :     uint8       hash[20];
                                347                 :     uint8       tmpbuf[20];
                                348                 :     uint8      *data;
                                349                 : 
                                350                 :     /* should not happen */
                                351              64 :     if (ctx->use_mdcbuf_filter)
 6482 bruce                     352 UBC           0 :         return PXE_BUG;
                                353                 : 
                                354                 :     /* It's SHA1 */
 2991 tgl                       355 CBC          64 :     if (len != 20)
 2991 tgl                       356 UBC           0 :         return PXE_PGP_CORRUPT_DATA;
                                357                 : 
                                358                 :     /* mdc_read should not call px_md_update */
 2991 tgl                       359 CBC          64 :     ctx->in_mdc_pkt = 1;
                                360                 : 
                                361                 :     /* read data */
                                362              64 :     res = pullf_read_max(src, len, &data, tmpbuf);
 6482 bruce                     363              64 :     if (res < 0)
 6482 bruce                     364 UBC           0 :         return res;
 6482 bruce                     365 CBC          64 :     if (res == 0)
                                366                 :     {
 2991 tgl                       367 UBC           0 :         px_debug("no mdc");
 6482 bruce                     368               0 :         return PXE_PGP_CORRUPT_DATA;
                                369                 :     }
                                370                 : 
                                371                 :     /* is the packet sane? */
 6482 bruce                     372 CBC          64 :     if (res != 20)
                                373                 :     {
 6482 bruce                     374 UBC           0 :         px_debug("mdc_finish: read failed, res=%d", res);
                                375               0 :         return PXE_PGP_CORRUPT_DATA;
                                376                 :     }
                                377                 : 
                                378                 :     /*
                                379                 :      * ok, we got the hash, now check
                                380                 :      */
 6482 bruce                     381 CBC          64 :     px_md_finish(ctx->mdc_ctx, hash);
 2991 tgl                       382              64 :     res = memcmp(hash, data, 20);
 3279 bruce                     383              64 :     px_memset(hash, 0, 20);
                                384              64 :     px_memset(tmpbuf, 0, sizeof(tmpbuf));
 6482                           385              64 :     if (res != 0)
                                386                 :     {
 6482 bruce                     387 UBC           0 :         px_debug("mdc_finish: mdc failed");
                                388               0 :         return PXE_PGP_CORRUPT_DATA;
                                389                 :     }
 6482 bruce                     390 CBC          64 :     ctx->mdc_checked = 1;
 2991 tgl                       391              64 :     return 0;
                                392                 : }
                                393                 : 
                                394                 : static int
 5050 bruce                     395             765 : mdc_read(void *priv, PullFilter *src, int len,
                                396                 :          uint8 **data_p, uint8 *buf, int buflen)
                                397                 : {
                                398                 :     int         res;
 6482                           399             765 :     PGP_Context *ctx = priv;
                                400                 : 
                                401                 :     /* skip this filter? */
 2991 tgl                       402             765 :     if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
 6482 bruce                     403             135 :         return pullf_read(src, len, data_p);
                                404                 : 
                                405             630 :     res = pullf_read(src, len, data_p);
                                406             630 :     if (res < 0)
 6482 bruce                     407 UBC           0 :         return res;
 6482 bruce                     408 CBC         630 :     if (res == 0)
                                409                 :     {
 6482 bruce                     410 UBC           0 :         px_debug("mdc_read: unexpected eof");
                                411               0 :         return PXE_PGP_CORRUPT_DATA;
                                412                 :     }
 6482 bruce                     413 CBC         630 :     px_md_update(ctx->mdc_ctx, *data_p, res);
                                414                 : 
                                415             630 :     return res;
                                416                 : }
                                417                 : 
                                418                 : static struct PullFilterOps mdc_filter = {
                                419                 :     mdc_init, mdc_read, mdc_free
                                420                 : };
                                421                 : 
                                422                 : 
                                423                 : /*
                                424                 :  * Combined Pkt reader and MDC hasher.
                                425                 :  *
                                426                 :  * For the case of SYMENCRYPTED_DATA_MDC packet, where
                                427                 :  * the data part has 'context length', which means
                                428                 :  * that data packet ends 22 bytes before end of parent
                                429                 :  * packet, which is silly.
                                430                 :  */
                                431                 : #define MDCBUF_LEN 8192
                                432                 : struct MDCBufData
                                433                 : {
                                434                 :     PGP_Context *ctx;
                                435                 :     int         eof;
                                436                 :     int         buflen;
                                437                 :     int         avail;
                                438                 :     uint8      *pos;
                                439                 :     int         mdc_avail;
                                440                 :     uint8       mdc_buf[22];
                                441                 :     uint8       buf[MDCBUF_LEN];
                                442                 : };
                                443                 : 
                                444                 : static int
 5050                           445               3 : mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
                                446                 : {
 6482                           447               3 :     PGP_Context *ctx = arg;
                                448                 :     struct MDCBufData *st;
                                449                 : 
  926 michael                   450               3 :     st = palloc0(sizeof(*st));
 6482 bruce                     451               3 :     st->buflen = sizeof(st->buf);
                                452               3 :     st->ctx = ctx;
                                453               3 :     *priv_p = st;
                                454                 : 
                                455                 :     /* take over the work of mdc_filter */
                                456               3 :     ctx->use_mdcbuf_filter = 1;
                                457                 : 
                                458               3 :     return 0;
                                459                 : }
                                460                 : 
                                461                 : static int
 2118 tgl                       462               3 : mdcbuf_finish(struct MDCBufData *st)
                                463                 : {
                                464                 :     uint8       hash[20];
                                465                 :     int         res;
                                466                 : 
 6482 bruce                     467               3 :     st->eof = 1;
                                468                 : 
                                469               3 :     if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
                                470                 :     {
                                471               2 :         px_debug("mdcbuf_finish: bad MDC pkt hdr");
                                472               2 :         return PXE_PGP_CORRUPT_DATA;
                                473                 :     }
                                474               1 :     px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
                                475               1 :     px_md_finish(st->ctx->mdc_ctx, hash);
                                476               1 :     res = memcmp(hash, st->mdc_buf + 2, 20);
 3279                           477               1 :     px_memset(hash, 0, 20);
 6482                           478               1 :     if (res)
                                479                 :     {
 6482 bruce                     480 UBC           0 :         px_debug("mdcbuf_finish: MDC does not match");
                                481               0 :         res = PXE_PGP_CORRUPT_DATA;
                                482                 :     }
 6482 bruce                     483 CBC           1 :     return res;
                                484                 : }
                                485                 : 
                                486                 : static void
 2118 tgl                       487               6 : mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
                                488                 : {
 6385 bruce                     489               6 :     uint8      *dst = st->pos + st->avail;
                                490                 : 
 6482                           491               6 :     memcpy(dst, src, len);
                                492               6 :     px_md_update(st->ctx->mdc_ctx, src, len);
                                493               6 :     st->avail += len;
                                494               6 : }
                                495                 : 
                                496                 : static void
 2118 tgl                       497               3 : mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
                                498                 : {
 6482 bruce                     499               3 :     memmove(st->mdc_buf + st->mdc_avail, src, len);
                                500               3 :     st->mdc_avail += len;
                                501               3 : }
                                502                 : 
                                503                 : static int
 2118 tgl                       504               6 : mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
                                505                 : {
                                506                 :     uint8      *data;
                                507                 :     int         res;
                                508                 :     int         need;
                                509                 : 
                                510                 :     /* put avail data in start */
 6482 bruce                     511               6 :     if (st->avail > 0 && st->pos != st->buf)
                                512               3 :         memmove(st->buf, st->pos, st->avail);
                                513               6 :     st->pos = st->buf;
                                514                 : 
                                515                 :     /* read new data */
                                516               6 :     need = st->buflen + 22 - st->avail - st->mdc_avail;
                                517               6 :     res = pullf_read(src, need, &data);
                                518               6 :     if (res < 0)
 6482 bruce                     519 UBC           0 :         return res;
 6482 bruce                     520 CBC           6 :     if (res == 0)
                                521               3 :         return mdcbuf_finish(st);
                                522                 : 
                                523                 :     /* add to buffer */
                                524               3 :     if (res >= 22)
                                525                 :     {
                                526               3 :         mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
                                527               3 :         st->mdc_avail = 0;
                                528                 : 
                                529               3 :         mdcbuf_load_data(st, data, res - 22);
                                530               3 :         mdcbuf_load_mdc(st, data + res - 22, 22);
                                531                 :     }
                                532                 :     else
                                533                 :     {
 6385 bruce                     534 UBC           0 :         int         canmove = st->mdc_avail + res - 22;
                                535                 : 
 6482                           536               0 :         if (canmove > 0)
                                537                 :         {
                                538               0 :             mdcbuf_load_data(st, st->mdc_buf, canmove);
                                539               0 :             st->mdc_avail -= canmove;
                                540               0 :             memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
                                541                 :         }
                                542               0 :         mdcbuf_load_mdc(st, data, res);
                                543                 :     }
 6482 bruce                     544 CBC           3 :     return 0;
                                545                 : }
                                546                 : 
                                547                 : static int
 5050                           548              10 : mdcbuf_read(void *priv, PullFilter *src, int len,
                                549                 :             uint8 **data_p, uint8 *buf, int buflen)
                                550                 : {
 6482                           551              10 :     struct MDCBufData *st = priv;
                                552                 :     int         res;
                                553                 : 
                                554              10 :     if (!st->eof && len > st->avail)
                                555                 :     {
                                556               6 :         res = mdcbuf_refill(st, src);
                                557               6 :         if (res < 0)
                                558               2 :             return res;
                                559                 :     }
                                560                 : 
                                561               8 :     if (len > st->avail)
                                562               2 :         len = st->avail;
                                563                 : 
                                564               8 :     *data_p = st->pos;
                                565               8 :     st->pos += len;
                                566               8 :     st->avail -= len;
                                567               8 :     return len;
                                568                 : }
                                569                 : 
                                570                 : static void
                                571               3 : mdcbuf_free(void *priv)
                                572                 : {
                                573               3 :     struct MDCBufData *st = priv;
                                574                 : 
                                575               3 :     px_md_free(st->ctx->mdc_ctx);
                                576               3 :     st->ctx->mdc_ctx = NULL;
 3279                           577               3 :     px_memset(st, 0, sizeof(*st));
  926 michael                   578               3 :     pfree(st);
 6482 bruce                     579               3 : }
                                580                 : 
                                581                 : static struct PullFilterOps mdcbuf_filter = {
                                582                 :     mdcbuf_init, mdcbuf_read, mdcbuf_free
                                583                 : };
                                584                 : 
                                585                 : 
                                586                 : /*
                                587                 :  * Decrypt separate session key
                                588                 :  */
                                589                 : static int
 5050                           590               4 : decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
                                591                 : {
                                592                 :     int         res;
                                593                 :     uint8       algo;
                                594                 :     PGP_CFB    *cfb;
                                595                 : 
 6482                           596               4 :     res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
 6385                           597               4 :                          ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
 6482                           598               4 :     if (res < 0)
 6482 bruce                     599 UBC           0 :         return res;
                                600                 : 
 6482 bruce                     601 CBC           4 :     pgp_cfb_decrypt(cfb, src, 1, &algo);
 6385                           602               4 :     src++;
                                603               4 :     len--;
                                604                 : 
 6482                           605               4 :     pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
                                606               4 :     pgp_cfb_free(cfb);
                                607               4 :     ctx->sess_key_len = len;
                                608               4 :     ctx->cipher_algo = algo;
                                609                 : 
 6385                           610               4 :     if (pgp_get_cipher_key_size(algo) != len)
                                611                 :     {
 6482 bruce                     612 UBC           0 :         px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
                                613                 :                  algo, pgp_get_cipher_key_size(algo), len);
                                614               0 :         return PXE_PGP_CORRUPT_DATA;
                                615                 :     }
 6482 bruce                     616 CBC           4 :     return 0;
                                617                 : }
                                618                 : 
                                619                 : /*
                                620                 :  * Handle key packet
                                621                 :  */
                                622                 : static int
 5050                           623              59 : parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
                                624                 : {
                                625                 :     uint8      *p;
                                626                 :     int         res;
                                627                 :     uint8       tmpbuf[PGP_MAX_KEY + 2];
                                628                 :     uint8       ver;
                                629                 : 
 6482                           630              59 :     GETBYTE(src, ver);
                                631              59 :     GETBYTE(src, ctx->s2k_cipher_algo);
                                632              59 :     if (ver != 4)
                                633                 :     {
 6482 bruce                     634 UBC           0 :         px_debug("bad key pkt ver");
                                635               0 :         return PXE_PGP_CORRUPT_DATA;
                                636                 :     }
                                637                 : 
                                638                 :     /*
                                639                 :      * read S2K info
                                640                 :      */
 6482 bruce                     641 CBC          59 :     res = pgp_s2k_read(src, &ctx->s2k);
                                642              59 :     if (res < 0)
 6482 bruce                     643 UBC           0 :         return res;
 6482 bruce                     644 CBC          59 :     ctx->s2k_mode = ctx->s2k.mode;
 2587 alvherre                  645              59 :     ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
 6482 bruce                     646              59 :     ctx->s2k_digest_algo = ctx->s2k.digest_algo;
                                647                 : 
                                648                 :     /*
                                649                 :      * generate key from password
                                650                 :      */
                                651              59 :     res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
                                652                 :                           ctx->sym_key, ctx->sym_key_len);
                                653              59 :     if (res < 0)
 6482 bruce                     654 UBC           0 :         return res;
                                655                 : 
                                656                 :     /*
                                657                 :      * do we have separate session key?
                                658                 :      */
 6482 bruce                     659 CBC          59 :     res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
                                660              59 :     if (res < 0)
 6482 bruce                     661 UBC           0 :         return res;
                                662                 : 
 6482 bruce                     663 CBC          59 :     if (res == 0)
                                664                 :     {
                                665                 :         /*
                                666                 :          * no, s2k key is session key
                                667                 :          */
                                668              55 :         memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
                                669              55 :         ctx->sess_key_len = ctx->s2k.key_len;
                                670              55 :         ctx->cipher_algo = ctx->s2k_cipher_algo;
                                671              55 :         res = 0;
                                672              55 :         ctx->use_sess_key = 0;
                                673                 :     }
                                674                 :     else
                                675                 :     {
                                676                 :         /*
                                677                 :          * yes, decrypt it
                                678                 :          */
                                679               4 :         if (res < 17 || res > PGP_MAX_KEY + 1)
                                680                 :         {
 6482 bruce                     681 UBC           0 :             px_debug("expect key, but bad data");
                                682               0 :             return PXE_PGP_CORRUPT_DATA;
                                683                 :         }
 6482 bruce                     684 CBC           4 :         ctx->use_sess_key = 1;
                                685               4 :         res = decrypt_key(ctx, p, res);
                                686                 :     }
                                687                 : 
 3279                           688              59 :     px_memset(tmpbuf, 0, sizeof(tmpbuf));
 6482                           689              59 :     return res;
                                690                 : }
                                691                 : 
                                692                 : static int
 5050                           693               2 : copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
                                694                 : {
 6385                           695               2 :     uint8      *data_end = data + len;
                                696                 :     uint8       tmpbuf[1024];
                                697               2 :     uint8      *tmp_end = tmpbuf + sizeof(tmpbuf);
                                698                 :     uint8      *p;
                                699                 :     int         res;
                                700                 : 
 6482                           701               2 :     p = tmpbuf;
 6385                           702               2 :     if (*got_cr)
                                703                 :     {
 6482 bruce                     704 UBC           0 :         if (*data != '\n')
                                705               0 :             *p++ = '\r';
                                706               0 :         *got_cr = 0;
                                707                 :     }
 6385 bruce                     708 CBC          47 :     while (data < data_end)
                                709                 :     {
 6482                           710              47 :         if (*data == '\r')
                                711                 :         {
                                712              14 :             if (data + 1 < data_end)
                                713                 :             {
                                714              12 :                 if (*(data + 1) == '\n')
                                715               7 :                     data++;
                                716                 :             }
                                717                 :             else
                                718                 :             {
                                719               2 :                 *got_cr = 1;
                                720               2 :                 break;
                                721                 :             }
                                722                 :         }
                                723              45 :         *p++ = *data++;
                                724              45 :         if (p >= tmp_end)
                                725                 :         {
 6482 bruce                     726 UBC           0 :             res = mbuf_append(dst, tmpbuf, p - tmpbuf);
                                727               0 :             if (res < 0)
                                728               0 :                 return res;
                                729               0 :             p = tmpbuf;
                                730                 :         }
                                731                 :     }
 6482 bruce                     732 CBC           2 :     if (p - tmpbuf > 0)
                                733                 :     {
                                734               2 :         res = mbuf_append(dst, tmpbuf, p - tmpbuf);
                                735               2 :         if (res < 0)
 6482 bruce                     736 UBC           0 :             return res;
                                737                 :     }
 3279 bruce                     738 CBC           2 :     px_memset(tmpbuf, 0, sizeof(tmpbuf));
 6482                           739               2 :     return 0;
                                740                 : }
                                741                 : 
                                742                 : static int
 5050                           743              67 : parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
                                744                 : {
                                745                 :     int         type;
                                746                 :     int         name_len;
                                747                 :     int         res;
                                748                 :     uint8      *buf;
                                749                 :     uint8       tmpbuf[4];
 6482                           750              67 :     int         got_cr = 0;
                                751                 : 
                                752              67 :     GETBYTE(pkt, type);
                                753              67 :     GETBYTE(pkt, name_len);
                                754                 : 
                                755                 :     /* skip name */
                                756              90 :     while (name_len > 0)
                                757                 :     {
                                758              23 :         res = pullf_read(pkt, name_len, &buf);
                                759              23 :         if (res < 0)
 6482 bruce                     760 UBC           0 :             return res;
 6482 bruce                     761 CBC          23 :         if (res == 0)
 6482 bruce                     762 UBC           0 :             break;
 6482 bruce                     763 CBC          23 :         name_len -= res;
                                764                 :     }
                                765              67 :     if (name_len > 0)
                                766                 :     {
 6482 bruce                     767 UBC           0 :         px_debug("parse_literal_data: unexpected eof");
                                768               0 :         return PXE_PGP_CORRUPT_DATA;
                                769                 :     }
                                770                 : 
                                771                 :     /* skip date */
 6482 bruce                     772 CBC          67 :     res = pullf_read_max(pkt, 4, &buf, tmpbuf);
                                773              67 :     if (res != 4)
                                774                 :     {
 6482 bruce                     775 UBC           0 :         px_debug("parse_literal_data: unexpected eof");
                                776               0 :         return PXE_PGP_CORRUPT_DATA;
                                777                 :     }
 3279 bruce                     778 CBC          67 :     px_memset(tmpbuf, 0, 4);
                                779                 : 
                                780                 :     /*
                                781                 :      * If called from an SQL function that returns text, pgp_decrypt() rejects
                                782                 :      * inputs not self-identifying as text.
                                783                 :      */
 6482                           784              67 :     if (ctx->text_mode)
                                785              63 :         if (type != 't' && type != 'u')
                                786                 :         {
                                787               4 :             px_debug("parse_literal_data: data type=%c", type);
 2883 noah                      788               4 :             ctx->unexpected_binary = true;
                                789                 :         }
                                790                 : 
 6482 bruce                     791              67 :     ctx->unicode_mode = (type == 'u') ? 1 : 0;
                                792                 : 
                                793                 :     /* read data */
                                794                 :     while (1)
                                795                 :     {
 6385                           796             155 :         res = pullf_read(pkt, 32 * 1024, &buf);
 6482                           797             155 :         if (res <= 0)
                                798              67 :             break;
                                799                 : 
                                800              88 :         if (ctx->text_mode && ctx->convert_crlf)
                                801               2 :             res = copy_crlf(dst, buf, res, &got_cr);
                                802                 :         else
                                803              86 :             res = mbuf_append(dst, buf, res);
                                804              88 :         if (res < 0)
 6482 bruce                     805 UBC           0 :             break;
                                806                 :     }
 6482 bruce                     807 CBC          67 :     if (res >= 0 && got_cr)
 6406 tgl                       808               2 :         res = mbuf_append(dst, (const uint8 *) "\r", 1);
 6482 bruce                     809              67 :     return res;
                                810                 : }
                                811                 : 
                                812                 : /* process_data_packets and parse_compressed_data call each other */
                                813                 : static int  process_data_packets(PGP_Context *ctx, MBuf *dst,
                                814                 :                                  PullFilter *src, int allow_compr, int need_mdc);
                                815                 : 
                                816                 : static int
 5050                           817               6 : parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
                                818                 : {
                                819                 :     int         res;
                                820                 :     uint8       type;
                                821                 :     PullFilter *pf_decompr;
                                822                 :     uint8      *discard_buf;
                                823                 : 
 6482                           824               6 :     GETBYTE(pkt, type);
                                825                 : 
                                826               6 :     ctx->compress_algo = type;
                                827               6 :     switch (type)
                                828                 :     {
 6482 bruce                     829 UBC           0 :         case PGP_COMPR_NONE:
                                830               0 :             res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
                                831               0 :             break;
                                832                 : 
 6482 bruce                     833 CBC           4 :         case PGP_COMPR_ZIP:
                                834                 :         case PGP_COMPR_ZLIB:
                                835               4 :             res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
                                836               4 :             if (res >= 0)
                                837                 :             {
                                838               4 :                 res = process_data_packets(ctx, dst, pf_decompr,
                                839                 :                                            NO_COMPR, NO_MDC);
                                840               4 :                 pullf_free(pf_decompr);
                                841                 :             }
                                842               4 :             break;
                                843                 : 
                                844               2 :         case PGP_COMPR_BZIP2:
                                845               2 :             px_debug("parse_compressed_data: bzip2 unsupported");
                                846                 :             /* report error in pgp_decrypt() */
 2883 noah                      847               2 :             ctx->unsupported_compr = 1;
                                848                 : 
                                849                 :             /*
                                850                 :              * Discard the compressed data, allowing it to first affect any
                                851                 :              * MDC digest computation.
                                852                 :              */
                                853                 :             while (1)
                                854                 :             {
                                855               3 :                 res = pullf_read(pkt, 32 * 1024, &discard_buf);
                                856               3 :                 if (res <= 0)
                                857               2 :                     break;
                                858                 :             }
                                859                 : 
 6482 bruce                     860               2 :             break;
                                861                 : 
 6482 bruce                     862 UBC           0 :         default:
                                863               0 :             px_debug("parse_compressed_data: unknown compr type");
                                864               0 :             res = PXE_PGP_CORRUPT_DATA;
                                865                 :     }
                                866                 : 
 6482 bruce                     867 CBC           6 :     return res;
                                868                 : }
                                869                 : 
                                870                 : static int
 5050                           871              76 : process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
                                872                 :                      int allow_compr, int need_mdc)
                                873                 : {
                                874                 :     uint8       tag;
                                875                 :     int         len,
                                876                 :                 res;
 6482                           877              76 :     int         got_data = 0;
                                878              76 :     int         got_mdc = 0;
                                879              76 :     PullFilter *pkt = NULL;
                                880                 : 
                                881                 :     while (1)
                                882                 :     {
                                883             211 :         res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
                                884             211 :         if (res <= 0)
                                885              73 :             break;
                                886                 : 
                                887                 : 
                                888                 :         /* mdc packet should be last */
                                889             138 :         if (got_mdc)
                                890                 :         {
 6482 bruce                     891 UBC           0 :             px_debug("process_data_packets: data after mdc");
                                892               0 :             res = PXE_PGP_CORRUPT_DATA;
                                893               0 :             break;
                                894                 :         }
                                895                 : 
                                896                 :         /*
                                897                 :          * Context length inside SYMENCRYPTED_DATA_MDC packet needs special
                                898                 :          * handling.
                                899                 :          */
 6482 bruce                     900 CBC         138 :         if (need_mdc && res == PKT_CONTEXT)
                                901               3 :             res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
                                902                 :         else
                                903             135 :             res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
                                904             138 :         if (res < 0)
 6482 bruce                     905 UBC           0 :             break;
                                906                 : 
 6482 bruce                     907 CBC         138 :         switch (tag)
                                908                 :         {
                                909              67 :             case PGP_PKT_LITERAL_DATA:
                                910              67 :                 got_data = 1;
                                911              67 :                 res = parse_literal_data(ctx, dst, pkt);
                                912              67 :                 break;
                                913               6 :             case PGP_PKT_COMPRESSED_DATA:
                                914               6 :                 if (allow_compr == 0)
                                915                 :                 {
 6482 bruce                     916 UBC           0 :                     px_debug("process_data_packets: unexpected compression");
                                917               0 :                     res = PXE_PGP_CORRUPT_DATA;
                                918                 :                 }
 6482 bruce                     919 CBC           6 :                 else if (got_data)
                                920                 :                 {
                                921                 :                     /*
                                922                 :                      * compr data must be alone
                                923                 :                      */
 6482 bruce                     924 UBC           0 :                     px_debug("process_data_packets: only one cmpr pkt allowed");
                                925               0 :                     res = PXE_PGP_CORRUPT_DATA;
                                926                 :                 }
                                927                 :                 else
                                928                 :                 {
 6482 bruce                     929 CBC           6 :                     got_data = 1;
                                930               6 :                     res = parse_compressed_data(ctx, dst, pkt);
                                931                 :                 }
                                932               6 :                 break;
                                933              64 :             case PGP_PKT_MDC:
                                934              64 :                 if (need_mdc == NO_MDC)
                                935                 :                 {
 6482 bruce                     936 UBC           0 :                     px_debug("process_data_packets: unexpected MDC");
                                937               0 :                     res = PXE_PGP_CORRUPT_DATA;
                                938               0 :                     break;
                                939                 :                 }
                                940                 : 
 2991 tgl                       941 CBC          64 :                 res = mdc_finish(ctx, pkt, len);
                                942              64 :                 if (res >= 0)
 6482 bruce                     943              64 :                     got_mdc = 1;
                                944              64 :                 break;
                                945               1 :             default:
                                946               1 :                 px_debug("process_data_packets: unexpected pkt tag=%d", tag);
                                947               1 :                 res = PXE_PGP_CORRUPT_DATA;
                                948                 :         }
                                949                 : 
                                950             138 :         pullf_free(pkt);
                                951             138 :         pkt = NULL;
                                952                 : 
                                953             138 :         if (res < 0)
                                954               3 :             break;
                                955                 :     }
                                956                 : 
                                957              76 :     if (pkt)
 6482 bruce                     958 UBC           0 :         pullf_free(pkt);
                                959                 : 
 6482 bruce                     960 CBC          76 :     if (res < 0)
                                961               5 :         return res;
                                962                 : 
                                963              71 :     if (!got_data)
                                964                 :     {
 6482 bruce                     965 UBC           0 :         px_debug("process_data_packets: no data");
                                966               0 :         res = PXE_PGP_CORRUPT_DATA;
                                967                 :     }
 6482 bruce                     968 CBC          71 :     if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
                                969                 :     {
 6482 bruce                     970 UBC           0 :         px_debug("process_data_packets: got no mdc");
                                971               0 :         res = PXE_PGP_CORRUPT_DATA;
                                972                 :     }
 6482 bruce                     973 CBC          71 :     return res;
                                974                 : }
                                975                 : 
                                976                 : static int
 5050                           977               2 : parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
                                978                 : {
                                979                 :     int         res;
 6385                           980               2 :     PGP_CFB    *cfb = NULL;
 6482                           981               2 :     PullFilter *pf_decrypt = NULL;
                                982               2 :     PullFilter *pf_prefix = NULL;
                                983                 : 
                                984               2 :     res = pgp_cfb_create(&cfb, ctx->cipher_algo,
 6385                           985               2 :                          ctx->sess_key, ctx->sess_key_len, 1, NULL);
 6482                           986               2 :     if (res < 0)
 6482 bruce                     987 UBC           0 :         goto out;
                                988                 : 
 6482 bruce                     989 CBC           2 :     res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
                                990               2 :     if (res < 0)
 6482 bruce                     991 UBC           0 :         goto out;
                                992                 : 
 6482 bruce                     993 CBC           2 :     res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
                                994               2 :     if (res < 0)
 6482 bruce                     995 UBC           0 :         goto out;
                                996                 : 
 6482 bruce                     997 CBC           2 :     res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
                                998                 : 
                                999               2 : out:
                               1000               2 :     if (pf_prefix)
                               1001               2 :         pullf_free(pf_prefix);
                               1002               2 :     if (pf_decrypt)
                               1003               2 :         pullf_free(pf_decrypt);
                               1004               2 :     if (cfb)
                               1005               2 :         pgp_cfb_free(cfb);
                               1006                 : 
                               1007               2 :     return res;
                               1008                 : }
                               1009                 : 
                               1010                 : static int
 5050                          1011              70 : parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
                               1012                 : {
                               1013                 :     int         res;
 6385                          1014              70 :     PGP_CFB    *cfb = NULL;
 6482                          1015              70 :     PullFilter *pf_decrypt = NULL;
                               1016              70 :     PullFilter *pf_prefix = NULL;
                               1017              70 :     PullFilter *pf_mdc = NULL;
                               1018                 :     uint8       ver;
                               1019                 : 
                               1020              70 :     GETBYTE(pkt, ver);
                               1021              70 :     if (ver != 1)
                               1022                 :     {
 6482 bruce                    1023 UBC           0 :         px_debug("parse_symenc_mdc_data: pkt ver != 1");
                               1024               0 :         return PXE_PGP_CORRUPT_DATA;
                               1025                 :     }
                               1026                 : 
 6482 bruce                    1027 CBC          70 :     res = pgp_cfb_create(&cfb, ctx->cipher_algo,
 6385                          1028              70 :                          ctx->sess_key, ctx->sess_key_len, 0, NULL);
 6482                          1029              70 :     if (res < 0)
 6482 bruce                    1030 UBC           0 :         goto out;
                               1031                 : 
 6482 bruce                    1032 CBC          70 :     res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
                               1033              70 :     if (res < 0)
 6482 bruce                    1034 UBC           0 :         goto out;
                               1035                 : 
 6482 bruce                    1036 CBC          70 :     res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
                               1037              70 :     if (res < 0)
 6482 bruce                    1038 UBC           0 :         goto out;
                               1039                 : 
 6482 bruce                    1040 CBC          70 :     res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
                               1041              70 :     if (res < 0)
 6482 bruce                    1042 UBC           0 :         goto out;
                               1043                 : 
 6482 bruce                    1044 CBC          70 :     res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
                               1045                 : 
                               1046              70 : out:
                               1047              70 :     if (pf_prefix)
                               1048              70 :         pullf_free(pf_prefix);
                               1049              70 :     if (pf_mdc)
                               1050              70 :         pullf_free(pf_mdc);
                               1051              70 :     if (pf_decrypt)
                               1052              70 :         pullf_free(pf_decrypt);
                               1053              70 :     if (cfb)
                               1054              70 :         pgp_cfb_free(cfb);
                               1055                 : 
                               1056              70 :     return res;
                               1057                 : }
                               1058                 : 
                               1059                 : /*
                               1060                 :  * skip over packet contents
                               1061                 :  */
                               1062                 : int
 5050                          1063             159 : pgp_skip_packet(PullFilter *pkt)
                               1064                 : {
 6385                          1065             159 :     int         res = 1;
                               1066                 :     uint8      *tmp;
                               1067                 : 
                               1068             472 :     while (res > 0)
                               1069             313 :         res = pullf_read(pkt, 32 * 1024, &tmp);
 3080 noah                     1070             159 :     return res;
                               1071                 : }
                               1072                 : 
                               1073                 : /*
                               1074                 :  * expect to be at packet end, any data is error
                               1075                 :  */
                               1076                 : int
 5050 bruce                    1077              27 : pgp_expect_packet_end(PullFilter *pkt)
                               1078                 : {
                               1079                 :     int         res;
                               1080                 :     uint8      *tmp;
                               1081                 : 
 3080 noah                     1082              27 :     res = pullf_read(pkt, 32 * 1024, &tmp);
                               1083              27 :     if (res > 0)
                               1084                 :     {
 3080 noah                     1085 UBC           0 :         px_debug("pgp_expect_packet_end: got data");
                               1086               0 :         return PXE_PGP_CORRUPT_DATA;
                               1087                 :     }
 3080 noah                     1088 CBC          27 :     return res;
                               1089                 : }
                               1090                 : 
                               1091                 : int
 5050 bruce                    1092              73 : pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
                               1093                 : {
                               1094                 :     int         res;
 6482                          1095              73 :     PullFilter *src = NULL;
                               1096              73 :     PullFilter *pkt = NULL;
                               1097                 :     uint8       tag;
                               1098                 :     int         len;
 6385                          1099              73 :     int         got_key = 0;
                               1100              73 :     int         got_data = 0;
                               1101                 : 
 6482                          1102              73 :     res = pullf_create_mbuf_reader(&src, msrc);
                               1103                 : 
 6385                          1104             218 :     while (res >= 0)
                               1105                 :     {
 6482                          1106             212 :         res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
                               1107             212 :         if (res <= 0)
                               1108              67 :             break;
                               1109                 : 
                               1110             145 :         res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
                               1111             145 :         if (res < 0)
 6482 bruce                    1112 UBC           0 :             break;
                               1113                 : 
 6482 bruce                    1114 CBC         145 :         res = PXE_PGP_CORRUPT_DATA;
 6385                          1115             145 :         switch (tag)
                               1116                 :         {
 6482 bruce                    1117 UBC           0 :             case PGP_PKT_MARKER:
                               1118               0 :                 res = pgp_skip_packet(pkt);
                               1119               0 :                 break;
 6482 bruce                    1120 CBC          14 :             case PGP_PKT_PUBENCRYPTED_SESSKEY:
                               1121                 :                 /* fixme: skip those */
                               1122              14 :                 res = pgp_parse_pubenc_sesskey(ctx, pkt);
                               1123              14 :                 got_key = 1;
                               1124              14 :                 break;
                               1125              59 :             case PGP_PKT_SYMENCRYPTED_SESSKEY:
                               1126              59 :                 if (got_key)
                               1127                 : 
                               1128                 :                     /*
                               1129                 :                      * Theoretically, there could be several keys, both public
                               1130                 :                      * and symmetric, all of which encrypt same session key.
                               1131                 :                      * Decrypt should try with each one, before failing.
                               1132                 :                      */
 6482 bruce                    1133 UBC           0 :                     px_debug("pgp_decrypt: using first of several keys");
                               1134                 :                 else
                               1135                 :                 {
 6482 bruce                    1136 CBC          59 :                     got_key = 1;
                               1137              59 :                     res = parse_symenc_sesskey(ctx, pkt);
                               1138                 :                 }
                               1139              59 :                 break;
                               1140               2 :             case PGP_PKT_SYMENCRYPTED_DATA:
                               1141               2 :                 if (!got_key)
 6482 bruce                    1142 UBC           0 :                     px_debug("pgp_decrypt: have data but no key");
 6482 bruce                    1143 CBC           2 :                 else if (got_data)
 6482 bruce                    1144 UBC           0 :                     px_debug("pgp_decrypt: got second data packet");
                               1145                 :                 else
                               1146                 :                 {
 6482 bruce                    1147 CBC           2 :                     got_data = 1;
                               1148               2 :                     ctx->disable_mdc = 1;
                               1149               2 :                     res = parse_symenc_data(ctx, pkt, mdst);
                               1150                 :                 }
                               1151               2 :                 break;
                               1152              70 :             case PGP_PKT_SYMENCRYPTED_DATA_MDC:
                               1153              70 :                 if (!got_key)
 6482 bruce                    1154 UBC           0 :                     px_debug("pgp_decrypt: have data but no key");
 6482 bruce                    1155 CBC          70 :                 else if (got_data)
 6482 bruce                    1156 UBC           0 :                     px_debug("pgp_decrypt: several data pkts not supported");
                               1157                 :                 else
                               1158                 :                 {
 6482 bruce                    1159 CBC          70 :                     got_data = 1;
                               1160              70 :                     ctx->disable_mdc = 0;
                               1161              70 :                     res = parse_symenc_mdc_data(ctx, pkt, mdst);
                               1162                 :                 }
                               1163              70 :                 break;
 6482 bruce                    1164 UBC           0 :             default:
                               1165               0 :                 px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
                               1166                 :         }
 6482 bruce                    1167 CBC         145 :         pullf_free(pkt);
                               1168             145 :         pkt = NULL;
                               1169                 :     }
                               1170                 : 
                               1171              73 :     if (pkt)
 6482 bruce                    1172 UBC           0 :         pullf_free(pkt);
                               1173                 : 
 6482 bruce                    1174 CBC          73 :     if (src)
                               1175              73 :         pullf_free(src);
                               1176                 : 
                               1177              73 :     if (res < 0)
                               1178               6 :         return res;
                               1179                 : 
                               1180                 :     /*
                               1181                 :      * Report a failure of the prefix_init() "quick check" now, rather than
                               1182                 :      * upon detection, to hinder timing attacks.  pgcrypto is not generally
                               1183                 :      * secure against timing attacks, but this helps.
                               1184                 :      */
                               1185              67 :     if (!got_data || ctx->corrupt_prefix)
 2883 noah                     1186 UBC           0 :         return PXE_PGP_CORRUPT_DATA;
                               1187                 : 
                               1188                 :     /*
                               1189                 :      * Code interpreting purportedly-decrypted data prior to this stage shall
                               1190                 :      * report no error other than PXE_PGP_CORRUPT_DATA.  (PXE_BUG is okay so
                               1191                 :      * long as it remains unreachable.)  This ensures that an attacker able to
                               1192                 :      * choose a ciphertext and receive a corresponding decryption error
                               1193                 :      * message cannot use that oracle to gather clues about the decryption
                               1194                 :      * key.  See "An Attack on CFB Mode Encryption As Used By OpenPGP" by
                               1195                 :      * Serge Mister and Robert Zuccherato.
                               1196                 :      *
                               1197                 :      * A problematic value in the first octet of a Literal Data or Compressed
                               1198                 :      * Data packet may indicate a simple user error, such as the need to call
                               1199                 :      * pgp_sym_decrypt_bytea instead of pgp_sym_decrypt.  Occasionally,
                               1200                 :      * though, it is the first symptom of the encryption key not matching the
                               1201                 :      * decryption key.  When this was the only problem encountered, report a
                               1202                 :      * specific error to guide the user; otherwise, we will have reported
                               1203                 :      * PXE_PGP_CORRUPT_DATA before now.  A key mismatch makes the other errors
                               1204                 :      * into red herrings, and this avoids leaking clues to attackers.
                               1205                 :      */
 2883 noah                     1206 CBC          67 :     if (ctx->unsupported_compr)
                               1207               1 :         return PXE_PGP_UNSUPPORTED_COMPR;
                               1208              66 :     if (ctx->unexpected_binary)
                               1209               3 :         return PXE_PGP_NOT_TEXT;
                               1210                 : 
 6482 bruce                    1211              63 :     return res;
                               1212                 : }
        

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