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 678 : get_cipher_info(int code)
94 : {
95 : const struct cipher_info *i;
96 :
97 3616 : for (i = cipher_list; i->name; i++)
98 3616 : if (i->code == code)
99 678 : return i;
100 0 : return NULL;
101 : }
102 :
103 : int
104 12 : pgp_get_digest_code(const char *name)
105 : {
106 : const struct digest_info *i;
107 :
108 18 : for (i = digest_list; i->name; i++)
109 18 : if (pg_strcasecmp(i->name, name) == 0)
110 12 : return i->code;
111 0 : return PXE_PGP_UNSUPPORTED_HASH;
112 : }
113 :
114 : int
115 28 : pgp_get_cipher_code(const char *name)
116 : {
117 : const struct cipher_info *i;
118 :
119 152 : for (i = cipher_list; i->name; i++)
120 152 : if (pg_strcasecmp(i->name, name) == 0)
121 28 : return i->code;
122 0 : return PXE_PGP_UNSUPPORTED_CIPHER;
123 : }
124 :
125 : const char *
126 466 : pgp_get_digest_name(int code)
127 : {
128 : const struct digest_info *i;
129 :
130 940 : for (i = digest_list; i->name; i++)
131 940 : if (i->code == code)
132 466 : return i->name;
133 0 : return NULL;
134 : }
135 :
136 : int
137 214 : pgp_get_cipher_key_size(int code)
138 : {
139 214 : const struct cipher_info *i = get_cipher_info(code);
140 :
141 214 : if (i != NULL)
142 214 : return i->key_len;
143 0 : return 0;
144 : }
145 :
146 : int
147 224 : pgp_get_cipher_block_size(int code)
148 : {
149 224 : const struct cipher_info *i = get_cipher_info(code);
150 :
151 224 : if (i != NULL)
152 224 : return i->block_len;
153 0 : return 0;
154 : }
155 :
156 : int
157 240 : pgp_load_cipher(int code, PX_Cipher **res)
158 : {
159 : int err;
160 240 : const struct cipher_info *i = get_cipher_info(code);
161 :
162 240 : if (i == NULL)
163 0 : return PXE_PGP_CORRUPT_DATA;
164 :
165 240 : err = px_find_cipher(i->int_name, res);
166 240 : if (err == 0)
167 240 : return 0;
168 :
169 0 : return PXE_PGP_UNSUPPORTED_CIPHER;
170 : }
171 :
172 : int
173 466 : pgp_load_digest(int code, PX_MD **res)
174 : {
175 : int err;
176 466 : const char *name = pgp_get_digest_name(code);
177 :
178 466 : if (name == NULL)
179 0 : return PXE_PGP_CORRUPT_DATA;
180 :
181 466 : err = px_find_digest(name, res);
182 466 : if (err == 0)
183 466 : return 0;
184 :
185 0 : return PXE_PGP_UNSUPPORTED_HASH;
186 : }
187 :
188 : int
189 230 : pgp_init(PGP_Context **ctx_p)
190 : {
191 : PGP_Context *ctx;
192 :
193 230 : ctx = palloc0(sizeof *ctx);
194 :
195 230 : ctx->cipher_algo = def_cipher_algo;
196 230 : ctx->s2k_cipher_algo = def_s2k_cipher_algo;
197 230 : ctx->s2k_mode = def_s2k_mode;
198 230 : ctx->s2k_count = def_s2k_count;
199 230 : ctx->s2k_digest_algo = def_s2k_digest_algo;
200 230 : ctx->compress_algo = def_compress_algo;
201 230 : ctx->compress_level = def_compress_level;
202 230 : ctx->disable_mdc = def_disable_mdc;
203 230 : ctx->use_sess_key = def_use_sess_key;
204 230 : ctx->unicode_mode = def_unicode_mode;
205 230 : ctx->convert_crlf = def_convert_crlf;
206 230 : ctx->text_mode = def_text_mode;
207 :
208 230 : *ctx_p = ctx;
209 230 : return 0;
210 : }
211 :
212 : int
213 230 : pgp_free(PGP_Context *ctx)
214 : {
215 230 : if (ctx->pub_key)
216 40 : pgp_key_free(ctx->pub_key);
217 230 : px_memset(ctx, 0, sizeof *ctx);
218 230 : pfree(ctx);
219 230 : return 0;
220 : }
221 :
222 : int
223 2 : pgp_disable_mdc(PGP_Context *ctx, int disable)
224 : {
225 2 : ctx->disable_mdc = disable ? 1 : 0;
226 2 : return 0;
227 : }
228 :
229 : int
230 10 : pgp_set_sess_key(PGP_Context *ctx, int use)
231 : {
232 10 : ctx->use_sess_key = use ? 1 : 0;
233 10 : return 0;
234 : }
235 :
236 : int
237 10 : pgp_set_convert_crlf(PGP_Context *ctx, int doit)
238 : {
239 10 : ctx->convert_crlf = doit ? 1 : 0;
240 10 : return 0;
241 : }
242 :
243 : int
244 6 : pgp_set_s2k_mode(PGP_Context *ctx, int mode)
245 : {
246 6 : int err = PXE_OK;
247 :
248 6 : switch (mode)
249 : {
250 6 : case PGP_S2K_SIMPLE:
251 : case PGP_S2K_SALTED:
252 : case PGP_S2K_ISALTED:
253 6 : ctx->s2k_mode = mode;
254 6 : break;
255 0 : default:
256 0 : err = PXE_ARGUMENT_ERROR;
257 0 : break;
258 : }
259 6 : return err;
260 : }
261 :
262 : int
263 4 : pgp_set_s2k_count(PGP_Context *ctx, int count)
264 : {
265 4 : if (ctx->s2k_mode == PGP_S2K_ISALTED && count >= 1024 && count <= 65011712)
266 : {
267 4 : ctx->s2k_count = count;
268 4 : return PXE_OK;
269 : }
270 0 : return PXE_ARGUMENT_ERROR;
271 : }
272 :
273 : int
274 10 : pgp_set_compress_algo(PGP_Context *ctx, int algo)
275 : {
276 10 : switch (algo)
277 : {
278 10 : case PGP_COMPR_NONE:
279 : case PGP_COMPR_ZIP:
280 : case PGP_COMPR_ZLIB:
281 : case PGP_COMPR_BZIP2:
282 10 : ctx->compress_algo = algo;
283 10 : return 0;
284 : }
285 0 : return PXE_ARGUMENT_ERROR;
286 : }
287 :
288 : int
289 4 : pgp_set_compress_level(PGP_Context *ctx, int level)
290 : {
291 4 : if (level >= 0 && level <= 9)
292 : {
293 4 : ctx->compress_level = level;
294 4 : return 0;
295 : }
296 0 : return PXE_ARGUMENT_ERROR;
297 : }
298 :
299 : int
300 230 : pgp_set_text_mode(PGP_Context *ctx, int mode)
301 : {
302 230 : ctx->text_mode = mode;
303 230 : return 0;
304 : }
305 :
306 : int
307 12 : pgp_set_cipher_algo(PGP_Context *ctx, const char *name)
308 : {
309 12 : int code = pgp_get_cipher_code(name);
310 :
311 12 : if (code < 0)
312 0 : return code;
313 12 : ctx->cipher_algo = code;
314 12 : return 0;
315 : }
316 :
317 : int
318 0 : pgp_set_s2k_cipher_algo(PGP_Context *ctx, const char *name)
319 : {
320 0 : int code = pgp_get_cipher_code(name);
321 :
322 0 : if (code < 0)
323 0 : return code;
324 0 : ctx->s2k_cipher_algo = code;
325 0 : return 0;
326 : }
327 :
328 : int
329 4 : pgp_set_s2k_digest_algo(PGP_Context *ctx, const char *name)
330 : {
331 4 : int code = pgp_get_digest_code(name);
332 :
333 4 : if (code < 0)
334 0 : return code;
335 4 : ctx->s2k_digest_algo = code;
336 4 : return 0;
337 : }
338 :
339 : int
340 214 : pgp_get_unicode_mode(PGP_Context *ctx)
341 : {
342 214 : return ctx->unicode_mode;
343 : }
344 :
345 : int
346 0 : pgp_set_unicode_mode(PGP_Context *ctx, int mode)
347 : {
348 0 : ctx->unicode_mode = mode ? 1 : 0;
349 0 : return 0;
350 : }
351 :
352 : int
353 178 : pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int len)
354 : {
355 178 : if (key == NULL || len < 1)
356 0 : return PXE_ARGUMENT_ERROR;
357 178 : ctx->sym_key = key;
358 178 : ctx->sym_key_len = len;
359 178 : return 0;
360 : }
|