(root)/
libxcrypt-4.4.36/
test/
checksalt.c
       1  /* Copyright (C) 2018-2021 Björn Esser <besser82@fedoraproject.org>
       2   *
       3   * Redistribution and use in source and binary forms, with or without
       4   * modification, are permitted.
       5   *
       6   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
       7   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       8   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
       9   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      10   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      11   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      12   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      13   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      14   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      15   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      16   * SUCH DAMAGE.
      17   */
      18  
      19  #include "crypt-port.h"
      20  #include <stdio.h>
      21  
      22  struct testcase
      23  {
      24    const char *prefix;
      25    const int exp_prefix;
      26    const int exp_gensalt;
      27    const int exp_crypt;
      28  };
      29  
      30  static const struct testcase testcases[] =
      31  {
      32  #if INCLUDE_descrypt || INCLUDE_bigcrypt
      33    { "",      CRYPT_SALT_INVALID,       CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      34    { "..",    CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      35    { "MN",    CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      36  #else
      37    { "",      CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      38    { "..",    CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      39    { "MN",    CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      40  #endif
      41  #if INCLUDE_bsdicrypt
      42    { "_",     CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      43  #else
      44    { "_",     CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      45  #endif
      46  #if INCLUDE_md5crypt
      47    { "$1$",   CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      48  #else
      49    { "$1$",   CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      50  #endif
      51  #if INCLUDE_nt
      52    { "$3$",   CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      53  #else
      54    { "$3$",   CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      55  #endif
      56  #if INCLUDE_sunmd5
      57    { "$md5",  CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      58  #else
      59    { "$md5",  CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      60  #endif
      61  #if INCLUDE_sha1crypt
      62    { "$sha1", CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      63  #else
      64    { "$sha1", CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      65  #endif
      66  #if INCLUDE_sha256crypt
      67    { "$5$",   CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_METHOD_LEGACY },
      68  #else
      69    { "$5$",   CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      70  #endif
      71  #if INCLUDE_sha512crypt
      72    { "$6$",   CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
      73  #else
      74    { "$6$",   CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      75  #endif
      76  #if INCLUDE_bcrypt
      77    { "$2b$",  CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
      78  #else
      79    { "$2b$",  CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      80  #endif
      81  #if INCLUDE_bcrypt_a
      82    { "$2a$",  CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
      83  #else
      84    { "$2a$",  CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      85  #endif
      86  #if INCLUDE_bcrypt_x
      87    { "$2x$",  CRYPT_SALT_METHOD_LEGACY, CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      88  #else
      89    { "$2x$",  CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      90  #endif
      91  #if INCLUDE_bcrypt_y
      92    { "$2y$",  CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
      93  #else
      94    { "$2y$",  CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
      95  #endif
      96  #if INCLUDE_yescrypt
      97    { "$y$",   CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
      98  #else
      99    { "$y$",   CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
     100  #endif
     101  #if INCLUDE_scrypt
     102    { "$7$",   CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
     103  #else
     104    { "$7$",   CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
     105  #endif
     106  #if INCLUDE_gost_yescrypt
     107    { "$gy$",  CRYPT_SALT_OK,            CRYPT_SALT_OK,            CRYPT_SALT_OK            },
     108  #else
     109    { "$gy$",  CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID,       CRYPT_SALT_INVALID       },
     110  #endif
     111  
     112    /* All of these are invalid. */
     113    { "$@",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     114    { "%A",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     115    { "A%",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     116    { "$2$",      CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     117    { "*0",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     118    { "*1",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     119    { "  ",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     120    { "!!",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     121    { "**",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     122    { "::",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     123    { ";;",       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     124    { "\\\\",     CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     125    { "\x01\x01", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     126    { "\x19\x19", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     127    { "\x20\x20", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     128    { "\x7f\x7f", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     129    { "\xfe\xfe", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     130    { "\xff\xff", CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     131  #if defined HASH_ALGORITHM_DEFAULT
     132    { NULL,       CRYPT_SALT_INVALID, CRYPT_SALT_OK,      CRYPT_SALT_OK      },
     133  #else
     134    { NULL,       CRYPT_SALT_INVALID, CRYPT_SALT_INVALID, CRYPT_SALT_INVALID },
     135  #endif
     136  };
     137  
     138  int
     139  main (void)
     140  {
     141    char gs_out[CRYPT_GENSALT_OUTPUT_SIZE] = "";
     142    const char *phr = "police saying freeze";
     143    struct crypt_data cd;
     144    const size_t gs_len = CRYPT_GENSALT_OUTPUT_SIZE;
     145  
     146    int status = 0;
     147    int retval = 0;
     148  
     149    for (size_t i = 0; i < ARRAY_SIZE (testcases); i++)
     150      {
     151        /* crypt_checksalt on prefix. */
     152        retval = crypt_checksalt (testcases[i].prefix);
     153        if (retval == testcases[i].exp_prefix)
     154          printf ("PASS (prefix): %s, result: %d\n",
     155                  testcases[i].prefix, retval);
     156        else
     157          {
     158            status = 1;
     159            printf ("FAIL (prefix): %s, expected: %d, got: %d\n",
     160                    testcases[i].prefix,
     161                    testcases[i].exp_prefix, retval);
     162            continue;
     163          }
     164  
     165        /* crypt_checksalt on gensalt output. */
     166        crypt_gensalt_rn (testcases[i].prefix, 0, NULL, 0,
     167                          gs_out, (int) gs_len);
     168        retval = crypt_checksalt (gs_out);
     169        if (retval == testcases[i].exp_gensalt)
     170          printf ("PASS (gensalt): %s, result: %d\n",
     171                  gs_out, retval);
     172        else
     173          {
     174            status = 1;
     175            printf ("FAIL (gensalt): %s, expected: %d, got: %d\n",
     176                    gs_out, testcases[i].exp_gensalt, retval);
     177            continue;
     178          }
     179  
     180        /* crypt_checksalt on crypt output. */
     181        crypt_r (phr, gs_out, &cd);
     182        retval = crypt_checksalt (cd.output);
     183        if (retval == testcases[i].exp_crypt)
     184          printf ("PASS (crypt): %s, result: %d\n",
     185                  cd.output, retval);
     186        else
     187          {
     188            status = 1;
     189            printf ("FAIL (crypt): %s, expected: %d, got: %d\n",
     190                    cd.output, testcases[i].exp_crypt, retval);
     191          }
     192  
     193  #if INCLUDE_descrypt && INCLUDE_bigcrypt
     194  
     195        /* Test bigcrypt as well. */
     196        if (testcases[i].prefix && strlen (testcases[i].prefix) == 2)
     197          {
     198            /* Prefix must be at least 14 bytes. */
     199            char bigcrypt_prefix[CRYPT_GENSALT_OUTPUT_SIZE];
     200            const char *pad = "............";
     201            memcpy (bigcrypt_prefix, testcases[i].prefix, 2);
     202            strncpy (bigcrypt_prefix + 2, pad, gs_len - 2);
     203  
     204            /* crypt_checksalt on prefix. */
     205            retval = crypt_checksalt (bigcrypt_prefix);
     206            if (retval == testcases[i].exp_prefix)
     207              printf ("PASS (prefix): %s, result: %d\n",
     208                      bigcrypt_prefix, retval);
     209            else
     210              {
     211                status = 1;
     212                printf ("FAIL (prefix): %s, expected: %d, got: %d\n",
     213                        bigcrypt_prefix,
     214                        testcases[i].exp_prefix, retval);
     215                continue;
     216              }
     217  
     218            /* crypt_checksalt on gensalt output. */
     219            crypt_gensalt_rn (bigcrypt_prefix, 0, NULL, 0,
     220                              gs_out, (int) gs_len);
     221  
     222            /* Add 12 trailing bytes. */
     223            strncpy (gs_out + 2, pad, gs_len - 2);
     224  
     225            retval = crypt_checksalt (gs_out);
     226            if (retval == testcases[i].exp_gensalt)
     227              printf ("PASS (gensalt): %s, result: %d\n",
     228                      gs_out, retval);
     229            else
     230              {
     231                status = 1;
     232                printf ("FAIL (gensalt): %s, expected: %d, got: %d\n",
     233                        gs_out, testcases[i].exp_gensalt, retval);
     234                continue;
     235              }
     236  
     237            /* crypt_checksalt on crypt output. */
     238            crypt_r (phr, gs_out, &cd);
     239            retval = crypt_checksalt (cd.output);
     240            if (retval == testcases[i].exp_crypt)
     241              printf ("PASS (crypt): %s, result: %d\n",
     242                      cd.output, retval);
     243            else
     244              {
     245                status = 1;
     246                printf ("FAIL (crypt): %s, expected: %d, got: %d\n",
     247                        cd.output, testcases[i].exp_crypt, retval);
     248              }
     249          }
     250  #endif
     251  
     252      }
     253  
     254    return status;
     255  }