LCOV - code coverage report
Current view: top level - contrib/pgcrypto - pgp.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 79.3 % 135 107
Test Date: 2026-03-04 08:14:57 Functions: 91.7 % 24 22
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * pgp.c
       3              :  *    Various utility stuff.
       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.c
      30              :  */
      31              : 
      32              : #include "postgres.h"
      33              : 
      34              : #include "pgp.h"
      35              : #include "px.h"
      36              : 
      37              : /*
      38              :  * Defaults.
      39              :  */
      40              : static int  def_cipher_algo = PGP_SYM_AES_128;
      41              : static int  def_s2k_cipher_algo = -1;
      42              : static int  def_s2k_mode = PGP_S2K_ISALTED;
      43              : static int  def_s2k_count = -1;
      44              : static int  def_s2k_digest_algo = PGP_DIGEST_SHA1;
      45              : static int  def_compress_algo = PGP_COMPR_NONE;
      46              : static int  def_compress_level = 6;
      47              : static int  def_disable_mdc = 0;
      48              : static int  def_use_sess_key = 0;
      49              : static int  def_text_mode = 0;
      50              : static int  def_unicode_mode = 0;
      51              : static int  def_convert_crlf = 0;
      52              : 
      53              : struct digest_info
      54              : {
      55              :     const char *name;
      56              :     int         code;
      57              : };
      58              : 
      59              : struct cipher_info
      60              : {
      61              :     const char *name;
      62              :     int         code;
      63              :     const char *int_name;
      64              :     int         key_len;
      65              :     int         block_len;
      66              : };
      67              : 
      68              : static const struct digest_info digest_list[] = {
      69              :     {"md5", PGP_DIGEST_MD5},
      70              :     {"sha1", PGP_DIGEST_SHA1},
      71              :     {"sha-1", PGP_DIGEST_SHA1},
      72              :     {"ripemd160", PGP_DIGEST_RIPEMD160},
      73              :     {"sha256", PGP_DIGEST_SHA256},
      74              :     {"sha384", PGP_DIGEST_SHA384},
      75              :     {"sha512", PGP_DIGEST_SHA512},
      76              :     {NULL, 0}
      77              : };
      78              : 
      79              : static const struct cipher_info cipher_list[] = {
      80              :     {"3des", PGP_SYM_DES3, "3des-ecb", 192 / 8, 64 / 8},
      81              :     {"cast5", PGP_SYM_CAST5, "cast5-ecb", 128 / 8, 64 / 8},
      82              :     {"bf", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
      83              :     {"blowfish", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
      84              :     {"aes", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
      85              :     {"aes128", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
      86              :     {"aes192", PGP_SYM_AES_192, "aes-ecb", 192 / 8, 128 / 8},
      87              :     {"aes256", PGP_SYM_AES_256, "aes-ecb", 256 / 8, 128 / 8},
      88              :     {"twofish", PGP_SYM_TWOFISH, "twofish-ecb", 256 / 8, 128 / 8},
      89              :     {NULL, 0, NULL}
      90              : };
      91              : 
      92              : static const struct cipher_info *
      93          342 : get_cipher_info(int code)
      94              : {
      95              :     const struct cipher_info *i;
      96              : 
      97         1823 :     for (i = cipher_list; i->name; i++)
      98         1823 :         if (i->code == code)
      99          342 :             return i;
     100            0 :     return NULL;
     101              : }
     102              : 
     103              : int
     104            6 : pgp_get_digest_code(const char *name)
     105              : {
     106              :     const struct digest_info *i;
     107              : 
     108            9 :     for (i = digest_list; i->name; i++)
     109            9 :         if (pg_strcasecmp(i->name, name) == 0)
     110            6 :             return i->code;
     111            0 :     return PXE_PGP_UNSUPPORTED_HASH;
     112              : }
     113              : 
     114              : int
     115           14 : pgp_get_cipher_code(const char *name)
     116              : {
     117              :     const struct cipher_info *i;
     118              : 
     119           76 :     for (i = cipher_list; i->name; i++)
     120           76 :         if (pg_strcasecmp(i->name, name) == 0)
     121           14 :             return i->code;
     122            0 :     return PXE_PGP_UNSUPPORTED_CIPHER;
     123              : }
     124              : 
     125              : const char *
     126          236 : pgp_get_digest_name(int code)
     127              : {
     128              :     const struct digest_info *i;
     129              : 
     130          476 :     for (i = digest_list; i->name; i++)
     131          476 :         if (i->code == code)
     132          236 :             return i->name;
     133            0 :     return NULL;
     134              : }
     135              : 
     136              : int
     137          108 : pgp_get_cipher_key_size(int code)
     138              : {
     139          108 :     const struct cipher_info *i = get_cipher_info(code);
     140              : 
     141          108 :     if (i != NULL)
     142          108 :         return i->key_len;
     143            0 :     return 0;
     144              : }
     145              : 
     146              : int
     147          113 : pgp_get_cipher_block_size(int code)
     148              : {
     149          113 :     const struct cipher_info *i = get_cipher_info(code);
     150              : 
     151          113 :     if (i != NULL)
     152          113 :         return i->block_len;
     153            0 :     return 0;
     154              : }
     155              : 
     156              : int
     157          121 : pgp_load_cipher(int code, PX_Cipher **res)
     158              : {
     159              :     int         err;
     160          121 :     const struct cipher_info *i = get_cipher_info(code);
     161              : 
     162          121 :     if (i == NULL)
     163            0 :         return PXE_PGP_CORRUPT_DATA;
     164              : 
     165          121 :     err = px_find_cipher(i->int_name, res);
     166          121 :     if (err == 0)
     167          121 :         return 0;
     168              : 
     169            0 :     return PXE_PGP_UNSUPPORTED_CIPHER;
     170              : }
     171              : 
     172              : int
     173          236 : pgp_load_digest(int code, PX_MD **res)
     174              : {
     175              :     int         err;
     176          236 :     const char *name = pgp_get_digest_name(code);
     177              : 
     178          236 :     if (name == NULL)
     179            0 :         return PXE_PGP_CORRUPT_DATA;
     180              : 
     181          236 :     err = px_find_digest(name, res);
     182          236 :     if (err == 0)
     183          236 :         return 0;
     184              : 
     185            0 :     return PXE_PGP_UNSUPPORTED_HASH;
     186              : }
     187              : 
     188              : int
     189          117 : pgp_init(PGP_Context **ctx_p)
     190              : {
     191              :     PGP_Context *ctx;
     192              : 
     193          117 :     ctx = palloc0(sizeof *ctx);
     194              : 
     195          117 :     ctx->cipher_algo = def_cipher_algo;
     196          117 :     ctx->s2k_cipher_algo = def_s2k_cipher_algo;
     197          117 :     ctx->s2k_mode = def_s2k_mode;
     198          117 :     ctx->s2k_count = def_s2k_count;
     199          117 :     ctx->s2k_digest_algo = def_s2k_digest_algo;
     200          117 :     ctx->compress_algo = def_compress_algo;
     201          117 :     ctx->compress_level = def_compress_level;
     202          117 :     ctx->disable_mdc = def_disable_mdc;
     203          117 :     ctx->use_sess_key = def_use_sess_key;
     204          117 :     ctx->unicode_mode = def_unicode_mode;
     205          117 :     ctx->convert_crlf = def_convert_crlf;
     206          117 :     ctx->text_mode = def_text_mode;
     207              : 
     208          117 :     *ctx_p = ctx;
     209          117 :     return 0;
     210              : }
     211              : 
     212              : int
     213          117 : pgp_free(PGP_Context *ctx)
     214              : {
     215          117 :     if (ctx->pub_key)
     216           21 :         pgp_key_free(ctx->pub_key);
     217          117 :     px_memset(ctx, 0, sizeof *ctx);
     218          117 :     pfree(ctx);
     219          117 :     return 0;
     220              : }
     221              : 
     222              : int
     223            1 : pgp_disable_mdc(PGP_Context *ctx, int disable)
     224              : {
     225            1 :     ctx->disable_mdc = disable ? 1 : 0;
     226            1 :     return 0;
     227              : }
     228              : 
     229              : int
     230            5 : pgp_set_sess_key(PGP_Context *ctx, int use)
     231              : {
     232            5 :     ctx->use_sess_key = use ? 1 : 0;
     233            5 :     return 0;
     234              : }
     235              : 
     236              : int
     237            5 : pgp_set_convert_crlf(PGP_Context *ctx, int doit)
     238              : {
     239            5 :     ctx->convert_crlf = doit ? 1 : 0;
     240            5 :     return 0;
     241              : }
     242              : 
     243              : int
     244            3 : pgp_set_s2k_mode(PGP_Context *ctx, int mode)
     245              : {
     246            3 :     int         err = PXE_OK;
     247              : 
     248            3 :     switch (mode)
     249              :     {
     250            3 :         case PGP_S2K_SIMPLE:
     251              :         case PGP_S2K_SALTED:
     252              :         case PGP_S2K_ISALTED:
     253            3 :             ctx->s2k_mode = mode;
     254            3 :             break;
     255            0 :         default:
     256            0 :             err = PXE_ARGUMENT_ERROR;
     257            0 :             break;
     258              :     }
     259            3 :     return err;
     260              : }
     261              : 
     262              : int
     263            2 : pgp_set_s2k_count(PGP_Context *ctx, int count)
     264              : {
     265            2 :     if (ctx->s2k_mode == PGP_S2K_ISALTED && count >= 1024 && count <= 65011712)
     266              :     {
     267            2 :         ctx->s2k_count = count;
     268            2 :         return PXE_OK;
     269              :     }
     270            0 :     return PXE_ARGUMENT_ERROR;
     271              : }
     272              : 
     273              : int
     274            5 : pgp_set_compress_algo(PGP_Context *ctx, int algo)
     275              : {
     276            5 :     switch (algo)
     277              :     {
     278            5 :         case PGP_COMPR_NONE:
     279              :         case PGP_COMPR_ZIP:
     280              :         case PGP_COMPR_ZLIB:
     281              :         case PGP_COMPR_BZIP2:
     282            5 :             ctx->compress_algo = algo;
     283            5 :             return 0;
     284              :     }
     285            0 :     return PXE_ARGUMENT_ERROR;
     286              : }
     287              : 
     288              : int
     289            2 : pgp_set_compress_level(PGP_Context *ctx, int level)
     290              : {
     291            2 :     if (level >= 0 && level <= 9)
     292              :     {
     293            2 :         ctx->compress_level = level;
     294            2 :         return 0;
     295              :     }
     296            0 :     return PXE_ARGUMENT_ERROR;
     297              : }
     298              : 
     299              : int
     300          117 : pgp_set_text_mode(PGP_Context *ctx, int mode)
     301              : {
     302          117 :     ctx->text_mode = mode;
     303          117 :     return 0;
     304              : }
     305              : 
     306              : int
     307            6 : pgp_set_cipher_algo(PGP_Context *ctx, const char *name)
     308              : {
     309            6 :     int         code = pgp_get_cipher_code(name);
     310              : 
     311            6 :     if (code < 0)
     312            0 :         return code;
     313            6 :     ctx->cipher_algo = code;
     314            6 :     return 0;
     315              : }
     316              : 
     317              : int
     318            0 : pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name)
     319              : {
     320            0 :     int         code = pgp_get_cipher_code(name);
     321              : 
     322            0 :     if (code < 0)
     323            0 :         return code;
     324            0 :     ctx->s2k_cipher_algo = code;
     325            0 :     return 0;
     326              : }
     327              : 
     328              : int
     329            2 : pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name)
     330              : {
     331            2 :     int         code = pgp_get_digest_code(name);
     332              : 
     333            2 :     if (code < 0)
     334            0 :         return code;
     335            2 :     ctx->s2k_digest_algo = code;
     336            2 :     return 0;
     337              : }
     338              : 
     339              : int
     340          109 : pgp_get_unicode_mode(PGP_Context *ctx)
     341              : {
     342          109 :     return ctx->unicode_mode;
     343              : }
     344              : 
     345              : int
     346            0 : pgp_set_unicode_mode(PGP_Context *ctx, int mode)
     347              : {
     348            0 :     ctx->unicode_mode = mode ? 1 : 0;
     349            0 :     return 0;
     350              : }
     351              : 
     352              : int
     353           90 : pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
     354              : {
     355           90 :     if (key == NULL || len < 1)
     356            0 :         return PXE_ARGUMENT_ERROR;
     357           90 :     ctx->sym_key = key;
     358           90 :     ctx->sym_key_len = len;
     359           90 :     return 0;
     360              : }
        

Generated by: LCOV version 2.0-1