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 28 : run_crypt_des(const char *psw, const char *salt,
39 : char *buf, unsigned len)
40 : {
41 : char *res;
42 :
43 28 : res = px_crypt_des(psw, salt);
44 24 : if (res == NULL || strlen(res) > len - 1)
45 4 : return NULL;
46 20 : strcpy(buf, res);
47 20 : return buf;
48 : }
49 :
50 : static char *
51 8 : run_crypt_md5(const char *psw, const char *salt,
52 : char *buf, unsigned len)
53 : {
54 : char *res;
55 :
56 8 : res = px_crypt_md5(psw, salt, buf, len);
57 8 : return res;
58 : }
59 :
60 : static char *
61 14 : run_crypt_bf(const char *psw, const char *salt,
62 : char *buf, unsigned len)
63 : {
64 : char *res;
65 :
66 14 : res = _crypt_blowfish_rn(psw, salt, buf, len);
67 8 : return res;
68 : }
69 :
70 : static char *
71 52 : run_crypt_sha(const char *psw, const char *salt,
72 : char *buf, unsigned len)
73 : {
74 : char *res;
75 :
76 52 : res = px_crypt_shacrypt(psw, salt, buf, len);
77 52 : 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 104 : px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
103 : {
104 : const struct px_crypt_algo *c;
105 :
106 104 : CheckBuiltinCryptoMode();
107 :
108 538 : for (c = px_crypt_list; c->id; c++)
109 : {
110 538 : if (!c->id_len)
111 10 : break;
112 528 : if (strncmp(salt, c->id, c->id_len) == 0)
113 92 : break;
114 : }
115 :
116 102 : if (c->crypt == NULL)
117 0 : return NULL;
118 :
119 102 : 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 28 : 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 28 : CheckBuiltinCryptoMode();
163 :
164 122 : for (g = gen_list; g->name; g++)
165 120 : if (pg_strcasecmp(g->name, salt_type) == 0)
166 24 : break;
167 :
168 26 : if (g->name == NULL)
169 2 : return PXE_UNKNOWN_SALT_ALGO;
170 :
171 24 : if (g->def_rounds)
172 : {
173 20 : if (rounds == 0)
174 4 : rounds = g->def_rounds;
175 :
176 20 : if (rounds < g->min_rounds || rounds > g->max_rounds)
177 8 : return PXE_BAD_SALT_ROUNDS;
178 : }
179 :
180 16 : if (!pg_strong_random(rbuf, g->input_len))
181 0 : return PXE_NO_RANDOM;
182 :
183 16 : p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
184 16 : px_memset(rbuf, 0, sizeof(rbuf));
185 :
186 16 : if (p == NULL)
187 0 : return PXE_BAD_SALT_ROUNDS;
188 :
189 16 : return strlen(p);
190 : }
|