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 : struct px_crypt_algo
71 : {
72 : char *id;
73 : unsigned id_len;
74 : char *(*crypt) (const char *psw, const char *salt,
75 : char *buf, unsigned len);
76 : };
77 :
78 : static const struct px_crypt_algo
79 : px_crypt_list[] = {
80 : {"$2a$", 4, run_crypt_bf},
81 : {"$2x$", 4, run_crypt_bf},
82 : {"$2$", 3, NULL}, /* N/A */
83 : {"$1$", 3, run_crypt_md5},
84 : {"_", 1, run_crypt_des},
85 : {"", 0, run_crypt_des},
86 : {NULL, 0, NULL}
87 : };
88 :
89 : char *
90 50 : px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
91 : {
92 : const struct px_crypt_algo *c;
93 :
94 196 : for (c = px_crypt_list; c->id; c++)
95 : {
96 196 : if (!c->id_len)
97 10 : break;
98 186 : if (strncmp(salt, c->id, c->id_len) == 0)
99 40 : break;
100 : }
101 :
102 50 : if (c->crypt == NULL)
103 0 : return NULL;
104 :
105 50 : return c->crypt(psw, salt, buf, len);
106 : }
107 :
108 : /*
109 : * salt generators
110 : */
111 :
112 : struct generator
113 : {
114 : char *name;
115 : char *(*gen) (unsigned long count, const char *input, int size,
116 : char *output, int output_size);
117 : int input_len;
118 : int def_rounds;
119 : int min_rounds;
120 : int max_rounds;
121 : };
122 :
123 : static struct generator gen_list[] = {
124 : {"des", _crypt_gensalt_traditional_rn, 2, 0, 0, 0},
125 : {"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0},
126 : {"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF},
127 : {"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31},
128 : {NULL, NULL, 0, 0, 0, 0}
129 : };
130 :
131 : int
132 10 : px_gen_salt(const char *salt_type, char *buf, int rounds)
133 : {
134 : struct generator *g;
135 : char *p;
136 : char rbuf[16];
137 :
138 30 : for (g = gen_list; g->name; g++)
139 28 : if (pg_strcasecmp(g->name, salt_type) == 0)
140 8 : break;
141 :
142 10 : if (g->name == NULL)
143 2 : return PXE_UNKNOWN_SALT_ALGO;
144 :
145 8 : if (g->def_rounds)
146 : {
147 4 : if (rounds == 0)
148 0 : rounds = g->def_rounds;
149 :
150 4 : if (rounds < g->min_rounds || rounds > g->max_rounds)
151 0 : return PXE_BAD_SALT_ROUNDS;
152 : }
153 :
154 8 : if (!pg_strong_random(rbuf, g->input_len))
155 0 : return PXE_NO_RANDOM;
156 :
157 8 : p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
158 8 : px_memset(rbuf, 0, sizeof(rbuf));
159 :
160 8 : if (p == NULL)
161 0 : return PXE_BAD_SALT_ROUNDS;
162 :
163 8 : return strlen(p);
164 : }
|