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