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