27:3e0325d39a61 | 28:8c61b29d87ec |
---|---|
17 const char *name; | 17 const char *name; |
18 unsigned long code; | 18 unsigned long code; |
19 }; | 19 }; |
20 typedef struct ssl_option_s ssl_option_t; | 20 typedef struct ssl_option_s ssl_option_t; |
21 | 21 |
22 /* The export DH key */ | |
23 static DH *dh_512 = NULL; | |
24 /* The larger key (builtin is 2048, caller may specify larger) */ | |
25 static DH *dh_larger = NULL; | |
26 | |
27 /* Generated via "openssl dhparam -2 -noout -C 512 2>/dev/null" */ | |
28 static unsigned char dh512_p[] = { | |
29 0xE4,0x3F,0x75,0x82,0xAD,0x0B,0x28,0xC7,0xEF,0xCE,0xBC,0x3B, | |
30 0x14,0xBB,0xA6,0xF4,0xA2,0xE9,0xA6,0x59,0xCF,0x97,0x1C,0x86, | |
31 0x43,0x3B,0x92,0x4A,0x6B,0x15,0x4B,0x0C,0xAC,0x8F,0xFA,0x43, | |
32 0xE2,0xA8,0xC3,0x3B,0x7B,0x51,0x1B,0x46,0x21,0xBF,0x8C,0x06, | |
33 0x6C,0xB1,0x49,0x75,0xC7,0xAC,0x47,0x1D,0x9D,0x64,0xD5,0x99, | |
34 0x33,0x86,0xAD,0xEB, | |
35 }; | |
36 | |
37 /* Generated via "openssl dhparam -2 -noout -C 2048 2>/dev/null" */ | |
38 static unsigned char dh2048_p[] = { | |
39 0x9B,0xF4,0xC5,0x57,0x81,0x8F,0xCF,0x31,0x78,0x95,0x04,0xCD, | |
40 0xEA,0xCC,0x30,0xEA,0xF7,0xCA,0x76,0xC8,0x8F,0x91,0xEA,0x0E, | |
41 0x44,0x8D,0xE2,0x63,0x19,0x3B,0x4D,0x04,0xC8,0x7D,0x0D,0xFF, | |
42 0x3D,0x52,0x76,0x02,0xF3,0xCA,0x1C,0x44,0xAF,0x0E,0xA9,0x59, | |
43 0x02,0x40,0x75,0xD6,0xED,0x35,0x4D,0x11,0x5B,0x2B,0x73,0x23, | |
44 0xE5,0x53,0x0B,0x1F,0xB0,0x47,0xC4,0x7F,0x95,0x5D,0xB0,0xD5, | |
45 0xF3,0xD3,0xAB,0x5F,0x28,0x2B,0xEC,0x2C,0x15,0x0B,0x1B,0x0C, | |
46 0xD4,0xBE,0x24,0x2F,0xC5,0x07,0x3C,0xE4,0xC5,0xE6,0x16,0x42, | |
47 0x4C,0x31,0x04,0xBB,0x80,0x96,0xFF,0x64,0x50,0xA4,0xA5,0xB5, | |
48 0xF5,0x3A,0xBA,0x57,0xE4,0xE6,0xC2,0x23,0x0A,0xB6,0x27,0xC4, | |
49 0x06,0x01,0x1E,0x98,0x20,0x09,0xC8,0xB7,0x90,0x09,0x86,0x06, | |
50 0xAA,0x85,0xE7,0x02,0xC8,0xC6,0xD9,0x1D,0xAB,0x17,0xEE,0x78, | |
51 0x73,0x78,0x88,0x7F,0xA7,0xF2,0x34,0xA7,0xDD,0x02,0x16,0x36, | |
52 0x0D,0x77,0x16,0x3E,0x95,0xAE,0x02,0xEE,0x36,0x37,0xD5,0x61, | |
53 0x5D,0xFE,0xC6,0x0B,0xDF,0xCE,0xB9,0x26,0x31,0x6F,0x34,0x92, | |
54 0xBB,0xBB,0x91,0x29,0x77,0x62,0x1D,0x75,0xA0,0x51,0x8D,0x31, | |
55 0x4C,0x64,0x4E,0xBF,0xDC,0xE8,0x67,0x17,0x90,0x6A,0x80,0xE9, | |
56 0xD7,0xD8,0x56,0x4E,0x85,0x21,0x9C,0xFB,0xE6,0x1B,0xD8,0x05, | |
57 0xFD,0x13,0x77,0x00,0x96,0x2D,0x0C,0x2A,0x95,0x1A,0x08,0x82, | |
58 0x2E,0xB3,0xE2,0xFC,0xE8,0xA6,0xF1,0x16,0x37,0x57,0x82,0xD6, | |
59 0xF5,0xAB,0xA9,0x43,0x8F,0x33,0xB0,0x57,0x38,0x6E,0x61,0xD4, | |
60 0xDD,0xE0,0x1C,0xCB, | |
61 }; | |
22 | 62 |
23 static ssl_option_t ssl_options[] = { | 63 static ssl_option_t ssl_options[] = { |
24 /* OpenSSL 0.9.7 and 0.9.8 */ | 64 /* OpenSSL 0.9.7 and 0.9.8 */ |
25 {"all", SSL_OP_ALL}, | 65 {"all", SSL_OP_ALL}, |
26 {"cipher_server_preference", SSL_OP_CIPHER_SERVER_PREFERENCE}, | 66 {"cipher_server_preference", SSL_OP_CIPHER_SERVER_PREFERENCE}, |
141 return (int)strlen(buf); | 181 return (int)strlen(buf); |
142 } | 182 } |
143 return 0; | 183 return 0; |
144 } | 184 } |
145 | 185 |
186 static DH *get_dh(const unsigned char *p, int len) | |
187 { | |
188 DH *dh = NULL; | |
189 static unsigned char g[] = { 0x02 }; | |
190 | |
191 if ((dh = DH_new()) == NULL) return NULL; | |
192 dh->p = BN_bin2bn(p, len, NULL); | |
193 dh->g = BN_bin2bn(g, sizeof(g), NULL); | |
194 if (dh->p == NULL || dh->g == NULL) { | |
195 DH_free(dh); | |
196 return NULL; | |
197 } | |
198 | |
199 return dh; | |
200 } | |
201 | |
202 /** | |
203 * DH parameter callback | |
204 */ | |
205 static DH *dh_param_cb(SSL *ssl, int is_export, int keylength) | |
206 { | |
207 /* Logic in postfix and dovecot, but we're using a 2048-bit group... */ | |
208 if (is_export && keylength == 512) { | |
209 if (dh_512 == NULL) { dh_512 = get_dh(dh512_p, sizeof(dh512_p)); } | |
210 return dh_512; | |
211 } else { | |
212 if (dh_larger == NULL) { dh_larger = get_dh(dh2048_p, sizeof(dh2048_p)); } | |
213 return dh_larger; | |
214 } | |
215 } | |
216 | |
217 | |
146 /*------------------------------ Lua Functions -------------------------------*/ | 218 /*------------------------------ Lua Functions -------------------------------*/ |
147 | 219 |
148 /** | 220 /** |
149 * Create a SSL context. | 221 * Create a SSL context. |
150 */ | 222 */ |
172 return 2; | 244 return 2; |
173 } | 245 } |
174 ctx->mode = MD_CTX_INVALID; | 246 ctx->mode = MD_CTX_INVALID; |
175 /* No session support */ | 247 /* No session support */ |
176 SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF); | 248 SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF); |
249 /* | |
250 * Support ephemeral diffie-hellman key exchange. This is only needed | |
251 * for server mode, but clearer to put it here rather than set_mode. | |
252 */ | |
253 SSL_CTX_set_tmp_dh_callback(ctx->context, dh_param_cb); | |
177 luaL_getmetatable(L, "SSL:Context"); | 254 luaL_getmetatable(L, "SSL:Context"); |
178 lua_setmetatable(L, -2); | 255 lua_setmetatable(L, -2); |
179 return 1; | 256 return 1; |
180 } | 257 } |
181 | 258 |
246 } | 323 } |
247 return ret; | 324 return ret; |
248 } | 325 } |
249 | 326 |
250 /** | 327 /** |
328 * Load a DH params files. This is a global LuaSec thing. | |
329 */ | |
330 static int load_dhparams(lua_State *L) | |
331 { | |
332 const char *filename = luaL_checkstring(L, 1); | |
333 FILE *paramfile; | |
334 DH *dh; | |
335 | |
336 paramfile = fopen(filename, "r"); | |
337 if (!paramfile) { | |
338 lua_pushboolean(L, 0); | |
339 lua_pushfstring(L, "error reading dh param file %s: %s", filename, | |
340 strerror(errno)); | |
341 return 2; | |
342 } | |
343 | |
344 dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL); | |
345 fclose(paramfile); | |
346 if (!dh) { | |
347 lua_pushboolean(L, 0); | |
348 lua_pushfstring(L, "error loading dh param file %s: %s", filename, | |
349 ERR_reason_error_string(ERR_get_error())); | |
350 return 2; | |
351 } | |
352 | |
353 if (dh_larger) | |
354 DH_free(dh_larger); | |
355 | |
356 dh_larger = dh; | |
357 | |
358 lua_pushboolean(L, 1); | |
359 return 1; | |
360 } | |
361 | |
362 /** | |
251 * Set the cipher list. | 363 * Set the cipher list. |
252 */ | 364 */ |
253 static int set_cipher(lua_State *L) | 365 static int set_cipher(lua_State *L) |
254 { | 366 { |
255 SSL_CTX *ctx = ctx_getcontext(L, 1); | 367 SSL_CTX *ctx = ctx_getcontext(L, 1); |
367 {"setdepth", set_depth}, | 479 {"setdepth", set_depth}, |
368 {"setverify", set_verify}, | 480 {"setverify", set_verify}, |
369 {"setoptions", set_options}, | 481 {"setoptions", set_options}, |
370 {"setmode", set_mode}, | 482 {"setmode", set_mode}, |
371 {"rawcontext", raw_ctx}, | 483 {"rawcontext", raw_ctx}, |
484 {"loaddhparams", load_dhparams}, | |
372 {NULL, NULL} | 485 {NULL, NULL} |
373 }; | 486 }; |
374 | 487 |
375 /*-------------------------------- Metamethods -------------------------------*/ | 488 /*-------------------------------- Metamethods -------------------------------*/ |
376 | 489 |