Header And Logo

PostgreSQL
| The world's most advanced open source database.

px-crypt.c

Go to the documentation of this file.
00001 /*
00002  * px-crypt.c
00003  *      Wrapper for various crypt algorithms.
00004  *
00005  * Copyright (c) 2001 Marko Kreen
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * contrib/pgcrypto/px-crypt.c
00030  */
00031 
00032 #include "postgres.h"
00033 
00034 #include "px.h"
00035 #include "px-crypt.h"
00036 
00037 
00038 static char *
00039 run_crypt_des(const char *psw, const char *salt,
00040               char *buf, unsigned len)
00041 {
00042     char       *res;
00043 
00044     res = px_crypt_des(psw, salt);
00045     if (strlen(res) > len - 1)
00046         return NULL;
00047     strcpy(buf, res);
00048     return buf;
00049 }
00050 
00051 static char *
00052 run_crypt_md5(const char *psw, const char *salt,
00053               char *buf, unsigned len)
00054 {
00055     char       *res;
00056 
00057     res = px_crypt_md5(psw, salt, buf, len);
00058     return res;
00059 }
00060 
00061 static char *
00062 run_crypt_bf(const char *psw, const char *salt,
00063              char *buf, unsigned len)
00064 {
00065     char       *res;
00066 
00067     res = _crypt_blowfish_rn(psw, salt, buf, len);
00068     return res;
00069 }
00070 
00071 struct px_crypt_algo
00072 {
00073     char       *id;
00074     unsigned    id_len;
00075     char       *(*crypt) (const char *psw, const char *salt,
00076                                       char *buf, unsigned len);
00077 };
00078 
00079 static const struct px_crypt_algo
00080             px_crypt_list[] = {
00081     {"$2a$", 4, run_crypt_bf},
00082     {"$2x$", 4, run_crypt_bf},
00083     {"$2$", 3, NULL},           /* N/A */
00084     {"$1$", 3, run_crypt_md5},
00085     {"_", 1, run_crypt_des},
00086     {"", 0, run_crypt_des},
00087     {NULL, 0, NULL}
00088 };
00089 
00090 char *
00091 px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
00092 {
00093     const struct px_crypt_algo *c;
00094 
00095     for (c = px_crypt_list; c->id; c++)
00096     {
00097         if (!c->id_len)
00098             break;
00099         if (strncmp(salt, c->id, c->id_len) == 0)
00100             break;
00101     }
00102 
00103     if (c->crypt == NULL)
00104         return NULL;
00105 
00106     return c->crypt(psw, salt, buf, len);
00107 }
00108 
00109 /*
00110  * salt generators
00111  */
00112 
00113 struct generator
00114 {
00115     char       *name;
00116     char       *(*gen) (unsigned long count, const char *input, int size,
00117                                     char *output, int output_size);
00118     int         input_len;
00119     int         def_rounds;
00120     int         min_rounds;
00121     int         max_rounds;
00122 };
00123 
00124 static struct generator gen_list[] = {
00125     {"des", _crypt_gensalt_traditional_rn, 2, 0, 0, 0},
00126     {"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
00127     {"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
00128     {"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
00129     {NULL, NULL, 0, 0, 0, 0}
00130 };
00131 
00132 int
00133 px_gen_salt(const char *salt_type, char *buf, int rounds)
00134 {
00135     int         res;
00136     struct generator *g;
00137     char       *p;
00138     char        rbuf[16];
00139 
00140     for (g = gen_list; g->name; g++)
00141         if (pg_strcasecmp(g->name, salt_type) == 0)
00142             break;
00143 
00144     if (g->name == NULL)
00145         return PXE_UNKNOWN_SALT_ALGO;
00146 
00147     if (g->def_rounds)
00148     {
00149         if (rounds == 0)
00150             rounds = g->def_rounds;
00151 
00152         if (rounds < g->min_rounds || rounds > g->max_rounds)
00153             return PXE_BAD_SALT_ROUNDS;
00154     }
00155 
00156     res = px_get_pseudo_random_bytes((uint8 *) rbuf, g->input_len);
00157     if (res < 0)
00158         return res;
00159 
00160     p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
00161     memset(rbuf, 0, sizeof(rbuf));
00162 
00163     if (p == NULL)
00164         return PXE_BAD_SALT_ROUNDS;
00165 
00166     return strlen(p);
00167 }