LCOV - code coverage report
Current view: top level - contrib/pgcrypto - px-crypt.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 93.2 % 44 41
Test Date: 2026-03-04 08:14:57 Functions: 100.0 % 6 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * px-crypt.c
       3              :  *      Wrapper for various crypt algorithms.
       4              :  *
       5              :  * Copyright (c) 2001 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/px-crypt.c
      30              :  */
      31              : 
      32              : #include "postgres.h"
      33              : 
      34              : #include "px-crypt.h"
      35              : #include "px.h"
      36              : 
      37              : static char *
      38           14 : run_crypt_des(const char *psw, const char *salt,
      39              :               char *buf, unsigned len)
      40              : {
      41              :     char       *res;
      42              : 
      43           14 :     res = px_crypt_des(psw, salt);
      44           12 :     if (res == NULL || strlen(res) > len - 1)
      45            2 :         return NULL;
      46           10 :     strcpy(buf, res);
      47           10 :     return buf;
      48              : }
      49              : 
      50              : static char *
      51            4 : run_crypt_md5(const char *psw, const char *salt,
      52              :               char *buf, unsigned len)
      53              : {
      54              :     char       *res;
      55              : 
      56            4 :     res = px_crypt_md5(psw, salt, buf, len);
      57            4 :     return res;
      58              : }
      59              : 
      60              : static char *
      61            7 : run_crypt_bf(const char *psw, const char *salt,
      62              :              char *buf, unsigned len)
      63              : {
      64              :     char       *res;
      65              : 
      66            7 :     res = _crypt_blowfish_rn(psw, salt, buf, len);
      67            4 :     return res;
      68              : }
      69              : 
      70              : static char *
      71           26 : run_crypt_sha(const char *psw, const char *salt,
      72              :               char *buf, unsigned len)
      73              : {
      74              :     char       *res;
      75              : 
      76           26 :     res = px_crypt_shacrypt(psw, salt, buf, len);
      77           26 :     return res;
      78              : }
      79              : 
      80              : struct px_crypt_algo
      81              : {
      82              :     char       *id;
      83              :     unsigned    id_len;
      84              :     char       *(*crypt) (const char *psw, const char *salt,
      85              :                           char *buf, unsigned len);
      86              : };
      87              : 
      88              : static const struct px_crypt_algo
      89              :             px_crypt_list[] = {
      90              :     {"$2a$", 4, run_crypt_bf},
      91              :     {"$2x$", 4, run_crypt_bf},
      92              :     {"$2$", 3, NULL},         /* N/A */
      93              :     {"$1$", 3, run_crypt_md5},
      94              :     {"$5$", 3, run_crypt_sha},
      95              :     {"$6$", 3, run_crypt_sha},
      96              :     {"_", 1, run_crypt_des},
      97              :     {"", 0, run_crypt_des},
      98              :     {NULL, 0, NULL}
      99              : };
     100              : 
     101              : char *
     102           52 : px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
     103              : {
     104              :     const struct px_crypt_algo *c;
     105              : 
     106           52 :     CheckBuiltinCryptoMode();
     107              : 
     108          269 :     for (c = px_crypt_list; c->id; c++)
     109              :     {
     110          269 :         if (!c->id_len)
     111            5 :             break;
     112          264 :         if (strncmp(salt, c->id, c->id_len) == 0)
     113           46 :             break;
     114              :     }
     115              : 
     116           51 :     if (c->crypt == NULL)
     117            0 :         return NULL;
     118              : 
     119           51 :     return c->crypt(psw, salt, buf, len);
     120              : }
     121              : 
     122              : /*
     123              :  * salt generators
     124              :  */
     125              : 
     126              : struct generator
     127              : {
     128              :     char       *name;
     129              :     char       *(*gen) (unsigned long count, const char *input, int size,
     130              :                         char *output, int output_size);
     131              :     int         input_len;
     132              :     int         def_rounds;
     133              :     int         min_rounds;
     134              :     int         max_rounds;
     135              : };
     136              : 
     137              : static struct generator gen_list[] = {
     138              :     {"des", _crypt_gensalt_traditional_rn, 2, 0, 0, 0},
     139              :     {"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
     140              :     {"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
     141              :     {"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
     142              :     {
     143              :         "sha256crypt", _crypt_gensalt_sha256_rn,
     144              :         PX_SHACRYPT_SALT_MAX_LEN, PX_SHACRYPT_ROUNDS_DEFAULT,
     145              :         PX_SHACRYPT_ROUNDS_MIN, PX_SHACRYPT_ROUNDS_MAX
     146              :     },
     147              :     {
     148              :         "sha512crypt", _crypt_gensalt_sha512_rn,
     149              :         PX_SHACRYPT_SALT_MAX_LEN, PX_SHACRYPT_ROUNDS_DEFAULT,
     150              :         PX_SHACRYPT_ROUNDS_MIN, PX_SHACRYPT_ROUNDS_MAX
     151              :     },
     152              :     {NULL, NULL, 0, 0, 0, 0}
     153              : };
     154              : 
     155              : int
     156           14 : px_gen_salt(const char *salt_type, char *buf, int rounds)
     157              : {
     158              :     struct generator *g;
     159              :     char       *p;
     160              :     char        rbuf[16];
     161              : 
     162           14 :     CheckBuiltinCryptoMode();
     163              : 
     164           61 :     for (g = gen_list; g->name; g++)
     165           60 :         if (pg_strcasecmp(g->name, salt_type) == 0)
     166           12 :             break;
     167              : 
     168           13 :     if (g->name == NULL)
     169            1 :         return PXE_UNKNOWN_SALT_ALGO;
     170              : 
     171           12 :     if (g->def_rounds)
     172              :     {
     173           10 :         if (rounds == 0)
     174            2 :             rounds = g->def_rounds;
     175              : 
     176           10 :         if (rounds < g->min_rounds || rounds > g->max_rounds)
     177            4 :             return PXE_BAD_SALT_ROUNDS;
     178              :     }
     179              : 
     180            8 :     if (!pg_strong_random(rbuf, g->input_len))
     181            0 :         return PXE_NO_RANDOM;
     182              : 
     183            8 :     p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
     184            8 :     px_memset(rbuf, 0, sizeof(rbuf));
     185              : 
     186            8 :     if (p == NULL)
     187            0 :         return PXE_BAD_SALT_ROUNDS;
     188              : 
     189            8 :     return strlen(p);
     190              : }
        

Generated by: LCOV version 2.0-1