Age Owner Branch data TLA 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 *
8782 bruce@momjian.us 38 :CBC 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);
3624 noah@leadboat.com 44 [ + + - + ]: 12 : if (res == NULL || strlen(res) > len - 1)
8782 bruce@momjian.us 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);
8749 67 : 4 : return res;
68 : : }
69 : :
70 : : static char *
154 alvherre@alvh.no-ip. 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 *
8782 bruce@momjian.us 102 : 52 : px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
103 : : {
104 : : const struct px_crypt_algo *c;
105 : :
225 dgustafsson@postgres 106 : 52 : CheckBuiltinCryptoMode();
107 : :
7474 neilc@samurai.com 108 [ + - ]: 269 : for (c = px_crypt_list; c->id; c++)
109 : : {
110 [ + + ]: 269 : if (!c->id_len)
8782 bruce@momjian.us 111 : 5 : break;
5002 peter_e@gmx.net 112 [ + + ]: 264 : if (strncmp(salt, c->id, c->id_len) == 0)
8782 bruce@momjian.us 113 : 46 : break;
114 : : }
115 : :
7474 neilc@samurai.com 116 [ - + ]: 51 : if (c->crypt == NULL)
8782 bruce@momjian.us 117 :UBC 0 : return NULL;
118 : :
7474 neilc@samurai.com 119 :CBC 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
8749 bruce@momjian.us 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 : :
225 dgustafsson@postgres 162 : 14 : CheckBuiltinCryptoMode();
163 : :
7474 neilc@samurai.com 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 : :
2440 michael@paquier.xyz 180 [ - + ]: 8 : if (!pg_strong_random(rbuf, g->input_len))
3197 heikki.linnakangas@i 181 :UBC 0 : return PXE_NO_RANDOM;
182 : :
7474 neilc@samurai.com 183 :CBC 8 : p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
4160 bruce@momjian.us 184 : 8 : px_memset(rbuf, 0, sizeof(rbuf));
185 : :
7474 neilc@samurai.com 186 [ - + ]: 8 : if (p == NULL)
7474 neilc@samurai.com 187 :UBC 0 : return PXE_BAD_SALT_ROUNDS;
188 : :
7474 neilc@samurai.com 189 :CBC 8 : return strlen(p);
190 : : }
|