TLA Line data Source code
1 : /*
2 : * pgp.c
3 : * Various utility stuff.
4 : *
5 : * Copyright (c) 2005 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/pgp.c
30 : */
31 :
32 : #include "postgres.h"
33 :
34 : #include "pgp.h"
35 : #include "px.h"
36 :
37 : /*
38 : * Defaults.
39 : */
40 : static int def_cipher_algo = PGP_SYM_AES_128;
41 : static int def_s2k_cipher_algo = -1;
42 : static int def_s2k_mode = PGP_S2K_ISALTED;
43 : static int def_s2k_count = -1;
44 : static int def_s2k_digest_algo = PGP_DIGEST_SHA1;
45 : static int def_compress_algo = PGP_COMPR_NONE;
46 : static int def_compress_level = 6;
47 : static int def_disable_mdc = 0;
48 : static int def_use_sess_key = 0;
49 : static int def_text_mode = 0;
50 : static int def_unicode_mode = 0;
51 : static int def_convert_crlf = 0;
52 :
53 : struct digest_info
54 : {
55 : const char *name;
56 : int code;
57 : };
58 :
59 : struct cipher_info
60 : {
61 : const char *name;
62 : int code;
63 : const char *int_name;
64 : int key_len;
65 : int block_len;
66 : };
67 :
68 : static const struct digest_info digest_list[] = {
69 : {"md5", PGP_DIGEST_MD5},
70 : {"sha1", PGP_DIGEST_SHA1},
71 : {"sha-1", PGP_DIGEST_SHA1},
72 : {"ripemd160", PGP_DIGEST_RIPEMD160},
73 : {"sha256", PGP_DIGEST_SHA256},
74 : {"sha384", PGP_DIGEST_SHA384},
75 : {"sha512", PGP_DIGEST_SHA512},
76 : {NULL, 0}
77 : };
78 :
79 : static const struct cipher_info cipher_list[] = {
80 : {"3des", PGP_SYM_DES3, "3des-ecb", 192 / 8, 64 / 8},
81 : {"cast5", PGP_SYM_CAST5, "cast5-ecb", 128 / 8, 64 / 8},
82 : {"bf", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
83 : {"blowfish", PGP_SYM_BLOWFISH, "bf-ecb", 128 / 8, 64 / 8},
84 : {"aes", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
85 : {"aes128", PGP_SYM_AES_128, "aes-ecb", 128 / 8, 128 / 8},
86 : {"aes192", PGP_SYM_AES_192, "aes-ecb", 192 / 8, 128 / 8},
87 : {"aes256", PGP_SYM_AES_256, "aes-ecb", 256 / 8, 128 / 8},
88 : {"twofish", PGP_SYM_TWOFISH, "twofish-ecb", 256 / 8, 128 / 8},
89 : {NULL, 0, NULL}
90 : };
91 :
92 : static const struct cipher_info *
93 CBC 339 : get_cipher_info(int code)
94 : {
95 : const struct cipher_info *i;
96 :
97 1808 : for (i = cipher_list; i->name; i++)
98 1808 : if (i->code == code)
99 339 : return i;
100 UBC 0 : return NULL;
101 : }
102 :
103 : int
104 CBC 6 : pgp_get_digest_code(const char *name)
105 : {
106 : const struct digest_info *i;
107 :
108 9 : for (i = digest_list; i->name; i++)
109 9 : if (pg_strcasecmp(i->name, name) == 0)
110 6 : return i->code;
111 UBC 0 : return PXE_PGP_UNSUPPORTED_HASH;
112 : }
113 :
114 : int
115 CBC 14 : pgp_get_cipher_code(const char *name)
116 : {
117 : const struct cipher_info *i;
118 :
119 76 : for (i = cipher_list; i->name; i++)
120 76 : if (pg_strcasecmp(i->name, name) == 0)
121 14 : return i->code;
122 UBC 0 : return PXE_PGP_UNSUPPORTED_CIPHER;
123 : }
124 :
125 : const char *
126 CBC 233 : pgp_get_digest_name(int code)
127 : {
128 : const struct digest_info *i;
129 :
130 470 : for (i = digest_list; i->name; i++)
131 470 : if (i->code == code)
132 233 : return i->name;
133 UBC 0 : return NULL;
134 : }
135 :
136 : int
137 CBC 107 : pgp_get_cipher_key_size(int code)
138 : {
139 107 : const struct cipher_info *i = get_cipher_info(code);
140 :
141 107 : if (i != NULL)
142 107 : return i->key_len;
143 UBC 0 : return 0;
144 : }
145 :
146 : int
147 CBC 112 : pgp_get_cipher_block_size(int code)
148 : {
149 GIC 112 : const struct cipher_info *i = get_cipher_info(code);
150 ECB :
151 GIC 112 : if (i != NULL)
152 CBC 112 : return i->block_len;
153 UBC 0 : return 0;
154 : }
155 ECB :
156 : int
157 CBC 120 : pgp_load_cipher(int code, PX_Cipher **res)
158 : {
159 EUB : int err;
160 GIC 120 : const struct cipher_info *i = get_cipher_info(code);
161 :
162 120 : if (i == NULL)
163 LBC 0 : return PXE_PGP_CORRUPT_DATA;
164 :
165 GIC 120 : err = px_find_cipher(i->int_name, res);
166 CBC 120 : if (err == 0)
167 GIC 120 : return 0;
168 ECB :
169 UBC 0 : return PXE_PGP_UNSUPPORTED_CIPHER;
170 : }
171 ECB :
172 : int
173 CBC 233 : pgp_load_digest(int code, PX_MD **res)
174 : {
175 EUB : int err;
176 GIC 233 : const char *name = pgp_get_digest_name(code);
177 :
178 233 : if (name == NULL)
179 LBC 0 : return PXE_PGP_CORRUPT_DATA;
180 :
181 GIC 233 : err = px_find_digest(name, res);
182 233 : if (err == 0)
183 CBC 233 : return 0;
184 :
185 LBC 0 : return PXE_PGP_UNSUPPORTED_HASH;
186 ECB : }
187 :
188 : int
189 CBC 115 : pgp_init(PGP_Context **ctx_p)
190 ECB : {
191 : PGP_Context *ctx;
192 :
193 CBC 115 : ctx = palloc0(sizeof *ctx);
194 ECB :
195 CBC 115 : ctx->cipher_algo = def_cipher_algo;
196 115 : ctx->s2k_cipher_algo = def_s2k_cipher_algo;
197 GIC 115 : ctx->s2k_mode = def_s2k_mode;
198 CBC 115 : ctx->s2k_count = def_s2k_count;
199 115 : ctx->s2k_digest_algo = def_s2k_digest_algo;
200 GIC 115 : ctx->compress_algo = def_compress_algo;
201 115 : ctx->compress_level = def_compress_level;
202 115 : ctx->disable_mdc = def_disable_mdc;
203 CBC 115 : ctx->use_sess_key = def_use_sess_key;
204 GIC 115 : ctx->unicode_mode = def_unicode_mode;
205 CBC 115 : ctx->convert_crlf = def_convert_crlf;
206 115 : ctx->text_mode = def_text_mode;
207 ECB :
208 CBC 115 : *ctx_p = ctx;
209 115 : return 0;
210 : }
211 :
212 : int
213 115 : pgp_free(PGP_Context *ctx)
214 : {
215 115 : if (ctx->pub_key)
216 20 : pgp_key_free(ctx->pub_key);
217 GIC 115 : px_memset(ctx, 0, sizeof *ctx);
218 115 : pfree(ctx);
219 115 : return 0;
220 ECB : }
221 :
222 : int
223 CBC 1 : pgp_disable_mdc(PGP_Context *ctx, int disable)
224 : {
225 GIC 1 : ctx->disable_mdc = disable ? 1 : 0;
226 1 : return 0;
227 ECB : }
228 :
229 : int
230 CBC 5 : pgp_set_sess_key(PGP_Context *ctx, int use)
231 : {
232 GIC 5 : ctx->use_sess_key = use ? 1 : 0;
233 5 : return 0;
234 ECB : }
235 :
236 : int
237 GIC 5 : pgp_set_convert_crlf(PGP_Context *ctx, int doit)
238 ECB : {
239 GIC 5 : ctx->convert_crlf = doit ? 1 : 0;
240 CBC 5 : return 0;
241 : }
242 :
243 ECB : int
244 CBC 3 : pgp_set_s2k_mode(PGP_Context *ctx, int mode)
245 EUB : {
246 GBC 3 : int err = PXE_OK;
247 EUB :
248 GIC 3 : switch (mode)
249 ECB : {
250 GIC 3 : case PGP_S2K_SIMPLE:
251 : case PGP_S2K_SALTED:
252 : case PGP_S2K_ISALTED:
253 CBC 3 : ctx->s2k_mode = mode;
254 GIC 3 : break;
255 LBC 0 : default:
256 UIC 0 : err = PXE_ARGUMENT_ERROR;
257 LBC 0 : break;
258 ECB : }
259 GIC 3 : return err;
260 EUB : }
261 :
262 : int
263 GIC 2 : pgp_set_s2k_count(PGP_Context *ctx, int count)
264 ECB : {
265 GIC 2 : if (ctx->s2k_mode == PGP_S2K_ISALTED && count >= 1024 && count <= 65011712)
266 ECB : {
267 GIC 2 : ctx->s2k_count = count;
268 CBC 2 : return PXE_OK;
269 : }
270 UIC 0 : return PXE_ARGUMENT_ERROR;
271 : }
272 ECB :
273 : int
274 GIC 5 : pgp_set_compress_algo(PGP_Context *ctx, int algo)
275 EUB : {
276 GIC 5 : switch (algo)
277 : {
278 5 : case PGP_COMPR_NONE:
279 ECB : case PGP_COMPR_ZIP:
280 : case PGP_COMPR_ZLIB:
281 : case PGP_COMPR_BZIP2:
282 GIC 5 : ctx->compress_algo = algo;
283 CBC 5 : return 0;
284 ECB : }
285 UIC 0 : return PXE_ARGUMENT_ERROR;
286 EUB : }
287 :
288 : int
289 GIC 2 : pgp_set_compress_level(PGP_Context *ctx, int level)
290 ECB : {
291 GIC 2 : if (level >= 0 && level <= 9)
292 ECB : {
293 CBC 2 : ctx->compress_level = level;
294 GIC 2 : return 0;
295 : }
296 UIC 0 : return PXE_ARGUMENT_ERROR;
297 ECB : }
298 :
299 : int
300 GIC 115 : pgp_set_text_mode(PGP_Context *ctx, int mode)
301 ECB : {
302 GBC 115 : ctx->text_mode = mode;
303 CBC 115 : return 0;
304 ECB : }
305 :
306 : int
307 GIC 6 : pgp_set_cipher_algo(PGP_Context *ctx, const char *name)
308 EUB : {
309 GIC 6 : int code = pgp_get_cipher_code(name);
310 EUB :
311 GIC 6 : if (code < 0)
312 UBC 0 : return code;
313 GBC 6 : ctx->cipher_algo = code;
314 6 : return 0;
315 EUB : }
316 :
317 : int
318 UIC 0 : pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name)
319 ECB : {
320 UIC 0 : int code = pgp_get_cipher_code(name);
321 ECB :
322 UIC 0 : if (code < 0)
323 LBC 0 : return code;
324 UBC 0 : ctx->s2k_cipher_algo = code;
325 LBC 0 : return 0;
326 ECB : }
327 :
328 : int
329 GIC 2 : pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name)
330 ECB : {
331 GIC 2 : int code = pgp_get_digest_code(name);
332 ECB :
333 GIC 2 : if (code < 0)
334 UIC 0 : return code;
335 GIC 2 : ctx->s2k_digest_algo = code;
336 GBC 2 : return 0;
337 : }
338 EUB :
339 : int
340 GIC 107 : pgp_get_unicode_mode(PGP_Context *ctx)
341 : {
342 107 : return ctx->unicode_mode;
343 ECB : }
344 :
345 : int
346 UBC 0 : pgp_set_unicode_mode(PGP_Context *ctx, int mode)
347 ECB : {
348 LBC 0 : ctx->unicode_mode = mode ? 1 : 0;
349 0 : return 0;
350 : }
351 :
352 : int
353 GIC 89 : pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
354 : {
355 89 : if (key == NULL || len < 1)
356 UIC 0 : return PXE_ARGUMENT_ERROR;
357 GIC 89 : ctx->sym_key = key;
358 89 : ctx->sym_key_len = len;
359 89 : return 0;
360 : }
|