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 *
8272 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);
3114 noah@leadboat.com 44 [ + + - + ]: 12 : if (res == NULL || strlen(res) > len - 1)
8272 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);
8239 67 : 4 : 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 *
8272 90 : 25 : px_crypt(const char *psw, const char *salt, char *buf, unsigned len)
91 : : {
92 : : const struct px_crypt_algo *c;
93 : :
6964 neilc@samurai.com 94 [ + - ]: 98 : for (c = px_crypt_list; c->id; c++)
95 : : {
96 [ + + ]: 98 : if (!c->id_len)
8272 bruce@momjian.us 97 : 5 : break;
4492 peter_e@gmx.net 98 [ + + ]: 93 : if (strncmp(salt, c->id, c->id_len) == 0)
8272 bruce@momjian.us 99 : 20 : break;
100 : : }
101 : :
6964 neilc@samurai.com 102 [ - + ]: 25 : if (c->crypt == NULL)
8272 bruce@momjian.us 103 :UBC 0 : return NULL;
104 : :
6964 neilc@samurai.com 105 :CBC 25 : 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
8239 bruce@momjian.us 132 : 5 : px_gen_salt(const char *salt_type, char *buf, int rounds)
133 : : {
134 : : struct generator *g;
135 : : char *p;
136 : : char rbuf[16];
137 : :
6964 neilc@samurai.com 138 [ + + ]: 15 : for (g = gen_list; g->name; g++)
139 [ + + ]: 14 : if (pg_strcasecmp(g->name, salt_type) == 0)
140 : 4 : break;
141 : :
142 [ + + ]: 5 : if (g->name == NULL)
143 : 1 : return PXE_UNKNOWN_SALT_ALGO;
144 : :
145 [ + + ]: 4 : if (g->def_rounds)
146 : : {
147 [ - + ]: 2 : if (rounds == 0)
6964 neilc@samurai.com 148 :UBC 0 : rounds = g->def_rounds;
149 : :
6964 neilc@samurai.com 150 [ + - - + ]:CBC 2 : if (rounds < g->min_rounds || rounds > g->max_rounds)
6964 neilc@samurai.com 151 :UBC 0 : return PXE_BAD_SALT_ROUNDS;
152 : : }
153 : :
1930 michael@paquier.xyz 154 [ - + ]:CBC 4 : if (!pg_strong_random(rbuf, g->input_len))
2687 heikki.linnakangas@i 155 :UBC 0 : return PXE_NO_RANDOM;
156 : :
6964 neilc@samurai.com 157 :CBC 4 : p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN);
3650 bruce@momjian.us 158 : 4 : px_memset(rbuf, 0, sizeof(rbuf));
159 : :
6964 neilc@samurai.com 160 [ - + ]: 4 : if (p == NULL)
6964 neilc@samurai.com 161 :UBC 0 : return PXE_BAD_SALT_ROUNDS;
162 : :
6964 neilc@samurai.com 163 :CBC 4 : return strlen(p);
164 : : }
|