LCOV - code coverage report
Current view: top level - common/utils - mcrypt.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 147 166 88.6 %
Date: 2021-10-27 03:06:47 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "mcrypt.h"
      11             : #include <string.h>
      12             : 
      13             : /* only provide digest functions if not embedded */
      14             : #include "sha.h"
      15             : #include "ripemd160.h"
      16             : #include "md5.h"
      17             : 
      18             : /**
      19             :  * Returns a comma separated list of supported hash algorithms suitable
      20             :  * for final hashing by the client.  This list contains the smaller
      21             :  * (in char size) hashes.
      22             :  * The returned string is malloced and should be freed.
      23             :  */
      24             : const char *
      25        5455 : mcrypt_getHashAlgorithms(void)
      26             : {
      27             :         /* Currently, four "hashes" are available, RIPEMD160, SHA-2, SHA-1
      28             :          * and MD5.  Previous versions supported UNIX crypt and plain text
      29             :          * login, but those were removed when SHA-1 became mandatory for
      30             :          * hashing the plain password in wire protocol version 9.
      31             :          * Better/stronger/faster algorithms can be added in the future upon
      32             :          * desire.
      33             :          */
      34             :         static const char *algorithms =
      35             :                 "INVALID"
      36             :                 ",RIPEMD160"
      37             :                 ",SHA512"
      38             :                 ",SHA384"
      39             :                 ",SHA256"
      40             :                 ",SHA224"
      41             :                 ",SHA1"
      42             : #ifdef HAVE_SNAPPY
      43             :                 ",COMPRESSION_SNAPPY"
      44             : #endif
      45             : #ifdef HAVE_LIBLZ4
      46             :                 ",COMPRESSION_LZ4"
      47             : #endif
      48             :                 ;
      49        5455 :         return algorithms;
      50             : }
      51             : 
      52             : /**
      53             :  * Returns a malloced string representing the hex representation of
      54             :  * the MD5 hash of the given string.
      55             :  */
      56             : char *
      57          12 : mcrypt_MD5Sum(const char *string, size_t len)
      58             : {
      59             :         MD5_CTX c;
      60             :         uint8_t md[MD5_DIGEST_LENGTH];
      61             :         char *ret;
      62             : 
      63             :         static_assert(MD5_DIGEST_LENGTH == 16, "MD5_DIGEST_LENGTH should be 16");
      64          12 :         MD5Init(&c);
      65          12 :         MD5Update(&c, (const uint8_t *) string, (unsigned int) len);
      66          12 :         MD5Final(md, &c);
      67             : 
      68          12 :         ret = malloc(MD5_DIGEST_LENGTH * 2 + 1);
      69          12 :         if(ret) {
      70          12 :                 snprintf(ret, MD5_DIGEST_LENGTH * 2 + 1,
      71             :                          "%02x%02x%02x%02x%02x%02x%02x%02x"
      72             :                          "%02x%02x%02x%02x%02x%02x%02x%02x",
      73          12 :                          md[0], md[1], md[2], md[3],
      74          12 :                          md[4], md[5], md[6], md[7],
      75          12 :                          md[8], md[9], md[10], md[11],
      76          12 :                          md[12], md[13], md[14], md[15]);
      77             :         }
      78             : 
      79          12 :         return ret;
      80             : }
      81             : 
      82             : /**
      83             :  * Returns a malloced string representing the hex representation of
      84             :  * the SHA-1 hash of the given string.
      85             :  */
      86             : char *
      87           4 : mcrypt_SHA1Sum(const char *string, size_t len)
      88             : {
      89             :         SHA1Context c;
      90             :         uint8_t md[SHA_DIGEST_LENGTH];
      91             :         char *ret;
      92             : 
      93             :         static_assert(SHA_DIGEST_LENGTH == SHA1HashSize, "SHA_DIGEST_LENGTH should be 20");
      94           4 :         SHA1Reset(&c);
      95           4 :         SHA1Input(&c, (const uint8_t *) string, (unsigned int) len);
      96           4 :         SHA1Result(&c, md);
      97             : 
      98           4 :         ret = malloc(SHA_DIGEST_LENGTH * 2 + 1);
      99           4 :         if(ret) {
     100           4 :                 snprintf(ret, SHA_DIGEST_LENGTH * 2 + 1,
     101             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     102             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
     103           4 :                          md[0], md[1], md[2], md[3], md[4],
     104           4 :                          md[5], md[6], md[7], md[8], md[9],
     105           4 :                          md[10], md[11], md[12], md[13], md[14],
     106           4 :                          md[15], md[16], md[17], md[18], md[19]);
     107             :         }
     108             : 
     109           4 :         return ret;
     110             : }
     111             : 
     112             : /**
     113             :  * Returns a malloced string representing the hex representation of
     114             :  * the SHA-224 hash of the given string.
     115             :  */
     116             : char *
     117           1 : mcrypt_SHA224Sum(const char *string, size_t len)
     118             : {
     119             :         SHA224Context c;
     120             :         uint8_t md[SHA224_DIGEST_LENGTH];
     121             :         char *ret;
     122             : 
     123             :         static_assert(SHA224_DIGEST_LENGTH == SHA224HashSize, "SHA224_DIGEST_LENGTH should be 28");
     124           1 :         SHA224Reset(&c);
     125           1 :         SHA224Input(&c, (const uint8_t *) string, (unsigned int) len);
     126           1 :         SHA224Result(&c, md);
     127             : 
     128           1 :         ret = malloc(SHA224_DIGEST_LENGTH * 2 + 1);
     129           1 :         if(ret) {
     130           1 :                 snprintf(ret, SHA224_DIGEST_LENGTH * 2 + 1,
     131             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     132             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     133             :                          "%02x%02x%02x%02x%02x%02x%02x%02x",
     134           1 :                          md[0], md[1], md[2], md[3], md[4],
     135           1 :                          md[5], md[6], md[7], md[8], md[9],
     136           1 :                          md[10], md[11], md[12], md[13], md[14],
     137           1 :                          md[15], md[16], md[17], md[18], md[19],
     138           1 :                          md[20], md[21], md[22], md[23], md[24],
     139           1 :                          md[25], md[26], md[27]);
     140             :         }
     141             : 
     142           1 :         return ret;
     143             : }
     144             : 
     145             : /**
     146             :  * Returns a malloced string representing the hex representation of
     147             :  * the SHA-256 hash of the given string.
     148             :  */
     149             : char *
     150           1 : mcrypt_SHA256Sum(const char *string, size_t len)
     151             : {
     152             :         SHA256Context c;
     153             :         uint8_t md[SHA256_DIGEST_LENGTH];
     154             :         char *ret;
     155             : 
     156             :         static_assert(SHA256_DIGEST_LENGTH == SHA256HashSize, "SHA256_DIGEST_LENGTH should be 32");
     157           1 :         SHA256Reset(&c);
     158           1 :         SHA256Input(&c, (const uint8_t *) string, (unsigned int) len);
     159           1 :         SHA256Result(&c, md);
     160             : 
     161           1 :         ret = malloc(SHA256_DIGEST_LENGTH * 2 + 1);
     162           1 :         if(ret) {
     163           1 :                 snprintf(ret, SHA256_DIGEST_LENGTH * 2 + 1,
     164             :                          "%02x%02x%02x%02x%02x%02x%02x%02x"
     165             :                          "%02x%02x%02x%02x%02x%02x%02x%02x"
     166             :                          "%02x%02x%02x%02x%02x%02x%02x%02x"
     167             :                          "%02x%02x%02x%02x%02x%02x%02x%02x",
     168           1 :                          md[0], md[1], md[2], md[3], md[4],
     169           1 :                          md[5], md[6], md[7], md[8], md[9],
     170           1 :                          md[10], md[11], md[12], md[13], md[14],
     171           1 :                          md[15], md[16], md[17], md[18], md[19],
     172           1 :                          md[20], md[21], md[22], md[23], md[24],
     173           1 :                          md[25], md[26], md[27], md[28], md[29],
     174           1 :                          md[30], md[31]);
     175             :         }
     176             : 
     177           1 :         return ret;
     178             : }
     179             : 
     180             : /**
     181             :  * Returns a malloced string representing the hex representation of
     182             :  * the SHA-384 hash of the given string.
     183             :  */
     184             : char *
     185           1 : mcrypt_SHA384Sum(const char *string, size_t len)
     186             : {
     187             :         SHA384Context c;
     188             :         uint8_t md[SHA384_DIGEST_LENGTH];
     189             :         char *ret;
     190             : 
     191             :         static_assert(SHA384_DIGEST_LENGTH == SHA384HashSize, "SHA384_DIGEST_LENGTH should be 48");
     192           1 :         SHA384Reset(&c);
     193           1 :         SHA384Input(&c, (const uint8_t *) string, (unsigned int) len);
     194           1 :         SHA384Result(&c, md);
     195             : 
     196           1 :         ret = malloc(SHA384_DIGEST_LENGTH * 2 + 1);
     197           1 :         if(ret) {
     198           1 :                 snprintf(ret, SHA384_DIGEST_LENGTH * 2 + 1,
     199             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     200             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     201             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     202             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     203             :                          "%02x%02x%02x%02x%02x%02x%02x%02x",
     204           1 :                          md[0], md[1], md[2], md[3], md[4],
     205           1 :                          md[5], md[6], md[7], md[8], md[9],
     206           1 :                          md[10], md[11], md[12], md[13], md[14],
     207           1 :                          md[15], md[16], md[17], md[18], md[19],
     208           1 :                          md[20], md[21], md[22], md[23], md[24],
     209           1 :                          md[25], md[26], md[27], md[28], md[29],
     210           1 :                          md[30], md[31], md[32], md[33], md[34],
     211           1 :                          md[35], md[36], md[37], md[38], md[39],
     212           1 :                          md[40], md[41], md[42], md[43], md[44],
     213           1 :                          md[45], md[46], md[47]);
     214             :         }
     215             : 
     216           1 :         return ret;
     217             : }
     218             : 
     219             : /**
     220             :  * Returns a malloced string representing the hex representation of
     221             :  * the SHA-512 hash of the given string.
     222             :  */
     223             : char *
     224         515 : mcrypt_SHA512Sum(const char *string, size_t len)
     225             : {
     226             :         SHA512Context c;
     227             :         uint8_t md[SHA512_DIGEST_LENGTH];
     228             :         char *ret;
     229             : 
     230             :         static_assert(SHA512_DIGEST_LENGTH == SHA512HashSize, "SHA512_DIGEST_LENGTH should be 64");
     231         515 :         SHA512Reset(&c);
     232         515 :         SHA512Input(&c, (const uint8_t *) string, (unsigned int) len);
     233         515 :         SHA512Result(&c, md);
     234             : 
     235         515 :         ret = malloc(SHA512_DIGEST_LENGTH * 2 + 1);
     236         515 :         if(ret) {
     237         515 :                 snprintf(ret, SHA512_DIGEST_LENGTH * 2 + 1,
     238             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     239             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     240             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     241             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     242             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     243             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     244             :                          "%02x%02x%02x%02x",
     245         515 :                          md[0], md[1], md[2], md[3], md[4],
     246         515 :                          md[5], md[6], md[7], md[8], md[9],
     247         515 :                          md[10], md[11], md[12], md[13], md[14],
     248         515 :                          md[15], md[16], md[17], md[18], md[19],
     249         515 :                          md[20], md[21], md[22], md[23], md[24],
     250         515 :                          md[25], md[26], md[27], md[28], md[29],
     251         515 :                          md[30], md[31], md[32], md[33], md[34],
     252         515 :                          md[35], md[36], md[37], md[38], md[39],
     253         515 :                          md[40], md[41], md[42], md[43], md[44],
     254         515 :                          md[45], md[46], md[47], md[48], md[49],
     255         515 :                          md[50], md[51], md[52], md[53], md[54],
     256         515 :                          md[55], md[56], md[57], md[58], md[59],
     257         515 :                          md[60], md[61], md[62], md[63]);
     258             :         }
     259             : 
     260         515 :         return ret;
     261             : }
     262             : 
     263             : /**
     264             :  * Returns a malloced string representing the hex representation of
     265             :  * the RIPEMD-160 hash of the given string.
     266             :  */
     267             : char *
     268           1 : mcrypt_RIPEMD160Sum(const char *string, size_t len)
     269             : {
     270             :         RIPEMD160Context c;
     271             :         uint8_t md[RIPEMD160_DIGEST_LENGTH];
     272             :         char *ret;
     273             : 
     274             :         static_assert(RIPEMD160_DIGEST_LENGTH == 20, "RIPEMD160_DIGEST_LENGTH should be 20");
     275           1 :         RIPEMD160Reset(&c);
     276           1 :         RIPEMD160Input(&c, (const uint8_t *) string, (unsigned int) len);
     277           1 :         RIPEMD160Result(&c, md);
     278             : 
     279           1 :         ret = malloc(RIPEMD160_DIGEST_LENGTH * 2 + 1);
     280           1 :         if(ret) {
     281           1 :                 snprintf(ret, RIPEMD160_DIGEST_LENGTH * 2 + 1,
     282             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     283             :                          "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
     284           1 :                          md[0], md[1], md[2], md[3], md[4],
     285           1 :                          md[5], md[6], md[7], md[8], md[9],
     286           1 :                          md[10], md[11], md[12], md[13], md[14],
     287           1 :                          md[15], md[16], md[17], md[18], md[19]);
     288             :         }
     289             : 
     290           1 :         return ret;
     291             : }
     292             : 
     293             : /**
     294             :  * Returns a malloced string representing the hex representation of
     295             :  * the by the backend used hash of the given string.
     296             :  */
     297             : #define concat(x,y,z)   x##y##z
     298             : #define mcryptsum(h)    concat(mcrypt_, h, Sum)
     299             : char *
     300         290 : mcrypt_BackendSum(const char *string, size_t len)
     301             : {
     302         290 :         return mcryptsum(MONETDB5_PASSWDHASH_TOKEN)(string, len);
     303             : }
     304             : 
     305             : /**
     306             :  * Returns the hash for the given password, challenge and algorithm.
     307             :  * The hash calculated using the given algorithm over the password
     308             :  * concatenated with the challenge.  The returned string is allocated
     309             :  * using malloc, and hence should be freed with free by the
     310             :  * caller.  Returns NULL when the given algorithm is not supported.
     311             :  */
     312             : char *
     313        6616 : mcrypt_hashPassword(
     314             :                 const char *algo,
     315             :                 const char *password,
     316             :                 const char *challenge)
     317             : {
     318             :         unsigned char md[64];   /* should be SHA512_DIGEST_LENGTH */
     319             :         char ret[sizeof(md) * 2 + 1];
     320             :         int len;
     321             : 
     322             :         /* make valgrind happy, prevent us from printing garbage afterwards */
     323        6616 :         memset(md, 0, sizeof(md));
     324             : 
     325        6616 :         if (strcmp(algo, "RIPEMD160") == 0) {
     326             :                 RIPEMD160Context c;
     327             : 
     328        6117 :                 RIPEMD160Reset(&c);
     329        6117 :                 RIPEMD160Input(&c, (const uint8_t *) password, (unsigned int) strlen(password));
     330        6117 :                 RIPEMD160Input(&c, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     331        6117 :                 RIPEMD160Result(&c, md);
     332             : 
     333             :                 len = 40;
     334         499 :         } else if (strcmp(algo, "SHA512") == 0) {
     335             :                 SHA512Context sc;
     336             : 
     337         162 :                 SHA512Reset(&sc);
     338         162 :                 SHA512Input(&sc, (const uint8_t *) password, (unsigned int) strlen(password));
     339         162 :                 SHA512Input(&sc, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     340         162 :                 SHA512Result(&sc, md);
     341             : 
     342             :                 len = 128;
     343         337 :         } else if (strcmp(algo, "SHA384") == 0) {
     344             :                 SHA384Context c;
     345             : 
     346           0 :                 SHA384Reset(&c);
     347           0 :                 SHA384Input(&c, (const uint8_t *) password, (unsigned int) strlen(password));
     348           0 :                 SHA384Input(&c, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     349           0 :                 SHA384Result(&c, md);
     350             : 
     351             :                 len = 96;
     352         337 :         } else if (strcmp(algo, "SHA256") == 0) {
     353             :                 SHA256Context c;
     354             : 
     355           0 :                 SHA256Reset(&c);
     356           0 :                 SHA256Input(&c, (const uint8_t *) password, (unsigned int) strlen(password));
     357           0 :                 SHA256Input(&c, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     358           0 :                 SHA256Result(&c, md);
     359             : 
     360             :                 len = 64;
     361         337 :         } else if (strcmp(algo, "SHA224") == 0) {
     362             :                 SHA224Context c;
     363             : 
     364           0 :                 SHA224Reset(&c);
     365           0 :                 SHA224Input(&c, (const uint8_t *) password, (unsigned int) strlen(password));
     366           0 :                 SHA224Input(&c, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     367           0 :                 SHA224Result(&c, md);
     368             : 
     369             :                 len = 56;
     370         337 :         } else if (strcmp(algo, "SHA1") == 0) {
     371             :                 SHA1Context c;
     372             : 
     373         337 :                 SHA1Reset(&c);
     374         337 :                 SHA1Input(&c, (const uint8_t *) password, (unsigned int) strlen(password));
     375         337 :                 SHA1Input(&c, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     376         337 :                 SHA1Result(&c, md);
     377             : 
     378             :                 len = 40;
     379           0 :         } else if (strcmp(algo, "MD5") == 0) {
     380             :                 MD5_CTX c;
     381             : 
     382           0 :                 MD5Init(&c);
     383           0 :                 MD5Update(&c, (const uint8_t *) password, (unsigned int) strlen(password));
     384           0 :                 MD5Update(&c, (const uint8_t *) challenge, (unsigned int) strlen(challenge));
     385           0 :                 MD5Final(md, &c);
     386             : 
     387             :                 len = 32;
     388             :         } else {
     389           0 :                 fprintf(stderr, "Unrecognized hash function (%s) requested.\n", algo);
     390           0 :                 return NULL;
     391             :         }
     392             : 
     393        6616 :         snprintf(ret, sizeof(ret),
     394             :                         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     395             :                         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     396             :                         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     397             :                         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     398             :                         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     399             :                         "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
     400             :                         "%02x%02x%02x%02x",
     401        6616 :                         md[0], md[1], md[2], md[3],
     402        6616 :                         md[4], md[5], md[6], md[7],
     403        6616 :                         md[8], md[9], md[10], md[11],
     404        6616 :                         md[12], md[13], md[14], md[15],
     405        6616 :                         md[16], md[17], md[18], md[19],
     406        6616 :                         md[20], md[21], md[22], md[23],
     407        6616 :                         md[24], md[25], md[26], md[27],
     408        6616 :                         md[28], md[29], md[30], md[31],
     409        6616 :                         md[32], md[33], md[34], md[35],
     410        6616 :                         md[36], md[37], md[38], md[39],
     411        6616 :                         md[40], md[41], md[42], md[43],
     412        6616 :                         md[44], md[45], md[46], md[47],
     413        6616 :                         md[48], md[49], md[50], md[51],
     414        6616 :                         md[52], md[53], md[54], md[55],
     415        6616 :                         md[56], md[57], md[58], md[59],
     416        6616 :                         md[60], md[61], md[62], md[63]);
     417        6616 :         ret[len] = '\0';
     418             : 
     419        6616 :         return strdup(ret);
     420             : }

Generated by: LCOV version 1.14