OSDN Git Service

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